windows-nt/Source/XPSP1/NT/drivers/wdm/capture/mini/avcstrm/avcdefs.h
2020-09-26 16:20:57 +08:00

545 lines
14 KiB
C

//
// Differnt level of WDM supports may use different API
//
// e.g. MmGetSystemAddressForMdl (win9x)
// Return NULL for Win9x; bugcheck for Win2000 if NULL would have returned.
//
// MmGetSystemAddressForMdlSafe (win2000)
// Not supported in Win9x or Millen
//
// This is defined in SOURCES file.
#define NUM_BUF_ATTACHED_THEN_ISOCH 4 // number of buffers attached before streaming and also as the water mark.
//
// These definition and macros are used to calculate the picture numbers.
// With OHCI spec, the data is returned with the 16bit Cycle time, which includes
// 3 bits of SecondCount and 13 bits of the CycleCount. This "timer" will wrap in 8 seconds.
//
#define TIME_PER_CYCLE 1250 // One 1394 cycle; unit = 100 nsec
#define CYCLES_PER_SECOND 8000
#define MAX_SECOND_COUNTS 7 // The returned CycleTime contains 3 bits of SecondCount; that is 0..7
#define MAX_CYCLES (MAX_SECOND_COUNTS + 1) * CYCLES_PER_SECOND // 0..MAX_CYCLES-1
#define MAX_CYCLES_TIME (MAX_CYCLES * TIME_PER_CYCLE) // unit = 100nsec
#define VALIDATE_CYCLE_COUNTS(CT) ASSERT(CT.CL_SecondCount <= 7 && CT.CL_CycleCount < CYCLES_PER_SECOND && CT.CL_CycleOffset == 0);
#define CALCULATE_CYCLE_COUNTS(CT) (CT.CL_SecondCount * CYCLES_PER_SECOND + CT.CL_CycleCount);
#define CALCULATE_DELTA_CYCLE_COUNT(prev, now) ((now > prev) ? now - prev : now + MAX_CYCLES - prev)
//
// Return avg time per frame in the unit of 100 nsec;
// for calculation accuracy using only integer calculation,
// we should do do multimplcation before division.
// That is why the application can request to get numerator and denominator separately.
//
#define GET_AVG_TIME_PER_FRAME(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? (1001000/3) : FRAME_TIME_PAL)
#define GET_AVG_TIME_PER_FRAME_NUM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 1001000 : 400000)
#define GET_AVG_TIME_PER_FRAME_DENOM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 3 : 1)
#define GET_NUM_PACKETS_PER_FRAME(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 4004/15 /* 100100/375 */ : MAX_SRC_PACKETS_PER_PAL_FRAME)
#define GET_NUM_PACKETS_PER_FRAME_NUM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 4004 : MAX_SRC_PACKETS_PER_PAL_FRAME)
#define GET_NUM_PACKETS_PER_FRAME_DENOM(format) ((format == AVCSTRM_FORMAT_SDDV_NTSC) ? 15 : 1)
//
// Structure used to keep track of and to perform stream data queuing
//
typedef struct _AVC_STREAM_DATA_STRUCT {
ULONG SizeOfThisPacket;
//
// Frame size is calculated based on
// CIP_DBS * 4 * (CIP_FN==0? 1 : (CIP_FN==1 ? 2 : (CIP_FN==2 ? 4 : 8)))
//
ULONG SourcePacketSize;
//
// Frame size is calculated based on
// SourcePacketSize * SRC_PACKETS_PER_***
//
ULONG FrameSize;
//
// Current stream time
//
LONGLONG CurrentStreamTime;
ULONG LastCycleCount; // Used only for MPEG2TS stream
//
// Statistic of the frame information since last start stream
// PictureNumber = FramesProcessed + FramesDropped + cndSRBCancelled.
//
LONGLONG PictureNumber;
LONGLONG FramesProcessed; // Frame made it to 1394 serial bus.
LONGLONG FramesDropped;
#if DBG
LONGLONG FramesAttached;
#endif
LONGLONG cntFrameCancelled;
//
// Count number of Data IRP received
//
LONGLONG cntDataReceived;
//
// Count and list for the attach list
//
LONG cntDataAttached;
LIST_ENTRY DataAttachedListHead;
//
// Count and list for the SRB list
//
LONG cntDataQueued; // Used only with SRB_WRITE_DATA
LIST_ENTRY DataQueuedListHead; // Used only with SRB_WRITE_DATA
//
// Count and list for the detach list
//
LONG cntDataDetached;
LIST_ENTRY DataDetachedListHead;
//
// Lock to serialize attach and detach of list
//
KSPIN_LOCK DataListLock;
//
// Memory blocked allocated at passive level for queuing data IOs.
//
PBYTE pMemoryBlock;
//
// Signalled when there is no more attach frame; mainoy used to guarantee that all
// data attached are transmitted before isoch is stopped for transmitting data
// from PC to AVC device.
//
KEVENT hNoAttachEvent;
} AVC_STREAM_DATA_STRUCT, * PAVC_STREAM_DATA_STRUCT;
typedef struct DEVICE_EXTENSION;
//
// An AVC stream extension is created per stream opened. This will be returned to the caller,
// when it will be used as the context (like a HANDLE) for subsequent call.
// The allocation will include
//
// AVC_STREAM_EXTENSION
// AV1394_FORMAT_INFO
// AV_CLIENT_REQ
//
typedef struct _AVC_STREAM_EXTENSION {
ULONG SizeOfThisPacket;
//
// This driver's device extension
//
struct DEVICE_EXTENSION * pDevExt;
//
// Data flow direction
//
KSPIN_DATAFLOW DataFlow; // Determine in or output pin
//
// Holds state
//
KSSTATE StreamState;
//
// This flag indicate if isoch is TALK/LISTEN or STOPPED
//
BOOLEAN IsochIsActive; // Close associated with StreamState
//
// Abstrction i/oPCR of an AVC device and PC itself as a plug handles
// Connection handle is used when two plugs are connected.
//
HANDLE hPlugRemote; // Target (DVCR,D-VHS) device plug;
HANDLE hPlugLocal; //.Local i/oPCR;
HANDLE hConnect; // Connect two plugs
//
// Structure for specifing an AVC stream
//
PAVCSTRM_FORMAT_INFO pAVCStrmFormatInfo;
//
// Structure for data flow control (IsochActive, IOQueues..etc)
//
PAVC_STREAM_DATA_STRUCT pAVCStrmDataStruc;
//
// Synchronizing setting stream control and processing data
//
KMUTEX hMutexControl;
//
// Synchronize sharing the below AV_61883_REQUEST structure
// Since all the stream control are synchronouse so we can use the same
// AV61883Req structure to issue 61883 request
//
KMUTEX hMutexAVReq;
PIRP pIrpAVReq;
AV_61883_REQUEST AVReq;
//
// Counter used to indicate starting of an work item to cancel
//
LONG lAbortToken;
//
// Hold the work item
//
#ifdef USE_WDM110 // Win2000 code base
PIO_WORKITEM pIoWorkItem;
#else
WORK_QUEUE_ITEM IoWorkItem;
#endif
//
// TO signal that an work item is completed.
//
KEVENT hAbortDoneEvent;
//
// Cached plug state (these are dynamic values)
//
CMP_GET_PLUG_STATE RemotePlugState;
#ifdef NT51_61883
//
// Cyclic cycle count of last DV frame
//
ULONG CycleCount16bits;
#endif // NT51_61883
//
// Keep track of the last system time when the stream time was updated.
// This is used to calibrate the current stream time when it is queries.
//
ULONGLONG LastSystemTime;
//
// Discontinuity is introduced when traistioning from RUN->PAUSE->RUN.
// The stream time will not increment in PAUSE state but system time (1394 CycleTime) does.
//
BOOL b1stNewFrameFromPauseState;
} AVC_STREAM_EXTENSION, *PAVC_STREAM_EXTENSION;
//
// Valid data entry states for a data request and they
// can be Or'ed to show their code path.
//
// Examples of different possible code path:
//
// (A) Attached -> Pending -> Callback -> Completed
// (B) Callback -> Attached -> Completed
// (C) Attached -> Cancelled -> Completed
//
enum DATA_ENTRY_STATE {
DE_PREPARED = 0x01,
DE_IRP_LOWER_ATTACHED_COMPLETED = 0x02,
DE_IRP_UPPER_PENDING_COMPLETED = 0x04,
DE_IRP_LOWER_CALLBACK_COMPLETED = 0x08,
DE_IRP_UPPER_COMPLETED = 0x10,
DE_IRP_ERROR = 0x20,
DE_IRP_CANCELLED = 0x40,
};
#define IsStateSet(state, bitmask) ((state & (bitmask)) == bitmask)
//
// This is the data entry used to attach a frame
//
typedef struct _AVCSTRM_DATA_ENTRY {
LIST_ENTRY ListEntry;
//
// Keep track of data entry state
//
enum DATA_ENTRY_STATE State;
//
// IRP from client of upper layer
//
PIRP pIrpUpper;
//
// Clock provider information
//
BOOL ClockProvider; // Client is a clock provider?
HANDLE ClockHandle; // This is used only if !ClockProvider; it is possible that there is no clock used.
//
// Contain information about this streaming buffer
//
PKSSTREAM_HEADER StreamHeader;
//
// Frame buffer
//
PVOID FrameBuffer;
//
// Stream extension (Context) of the stream of this frame
//
PAVC_STREAM_EXTENSION pAVCStrmExt;
#if DBG
//
// Add debug related info here
//
LONGLONG FrameNumber;
#endif
//
// 61883 CIP frame structure
//
struct _CIP_FRAME * Frame;
//
// IRP used to send to 61883 (lower layer) for AV request, such as attach and release
//
PIRP pIrpLower;
//
// Use to send 61883 AV data request
//
AV_61883_REQUEST AVReq;
} AVCSTRM_DATA_ENTRY, *PAVCSTRM_DATA_ENTRY;
//
// To open a stream.
// A context is created and return to the caller. This context is need for all
// stream operation.
//
NTSTATUS
AVCStreamOpen(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN OUT AVCSTRM_OPEN_STRUCT * pOpenStruct
);
// To Close a stram.
NTSTATUS
AVCStreamClose(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
//
// Process stream control
//
NTSTATUS
AVCStreamControlGetState(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
OUT KSSTATE * pKSState
);
NTSTATUS
AVCStreamControlSetState(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN KSSTATE KSState
);
NTSTATUS
AVCStreamControlGetProperty(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN PSTREAM_PROPERTY_DESCRIPTOR pSPD // BUGBUG StreamClass specific
);
NTSTATUS
AVCStreamControlSetProperty(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN PSTREAM_PROPERTY_DESCRIPTOR pSPD // BUGBUG StreamClass specific
);
// Process SRB_READ/WRITE_DATA; this is the only IRPs that will operate asychronously
// with. and STATUS_PENDING is returned.
NTSTATUS
AVCStreamRead(
IN PIRP pIrpUpper,
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN AVCSTRM_BUFFER_STRUCT * pBufferStruct
);
NTSTATUS
AVCStreamWrite(
IN PIRP pIrpUpper,
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN AVCSTRM_BUFFER_STRUCT * pBufferStruct
);
/*
This will stop streaming and cancel all pending data irps. This is typically used
to cancel all Irps. To cancel a single Irp, use IoCancelIrp().
*/
NTSTATUS
AVCStreamAbortStreaming(
IN PIRP pIrp, // The Irp from its client
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
/*
Process surprise removal of a device
*/
NTSTATUS
AVCStreamSurpriseRemoval(
IN struct DEVICE_EXTENSION * pDevExt
);
////////////////////////////////
// AvcUtil.c function prototypes
////////////////////////////////
ULONGLONG
GetSystemTime(
)
;
NTSTATUS
AVCStrmAttachFrameCR(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp,
IN PAVCSTRM_DATA_ENTRY pDataEntry
);
VOID
AVCStrmFormatAttachFrame(
IN KSPIN_DATAFLOW DataFlow,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN AVCSTRM_FORMAT AVCStrmFormat,
IN PAV_61883_REQUEST pAVReq,
IN PAVCSTRM_DATA_ENTRY pDataEntry,
IN ULONG ulSourcePacketSize, // Packet length in bytes
IN ULONG ulFrameSize, // Buffer size; may contain one or multiple source packets
IN PIRP pIrpUpper,
IN PKSSTREAM_HEADER StreamHeader,
IN PVOID FrameBuffer
);
NTSTATUS
AVCStrmGetPlugHandle(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmGetPlugState(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmGetConnectionProperty(
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
PSTREAM_PROPERTY_DESCRIPTOR pSPD,
PULONG pulActualBytesTransferred
);
NTSTATUS
AVCStrmGetDroppedFramesProperty(
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
PSTREAM_PROPERTY_DESCRIPTOR pSPD,
PULONG pulBytesTransferred
);
NTSTATUS
AVCStrmMakeConnection(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmBreakConnection(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmStartIsoch(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmStopIsoch(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
VOID
AVCStrmWaitUntilAttachedAreCompleted(
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmAllocateQueues(
IN struct DEVICE_EXTENSION * pDevExt,
IN PAVC_STREAM_EXTENSION pAVCStrmExt,
IN KSPIN_DATAFLOW DataFlow,
IN PAVC_STREAM_DATA_STRUCT pDataStruc,
PAVCSTRM_FORMAT_INFO pAVCStrmFormatInfo
);
NTSTATUS
AVCStrmFreeQueues(
IN PAVC_STREAM_DATA_STRUCT pDataStruc
);
NTSTATUS
AVCStrmCancelIO(
IN PDEVICE_OBJECT DeviceObject,
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);
NTSTATUS
AVCStrmValidateFormat(
PAVCSTRM_FORMAT_INFO pAVCFormatInfo
);
void
AVCStrmAbortStreamingWorkItemRoutine(
#ifdef USE_WDM110 // Win2000 code base
// Extra parameter if using WDM10
PDEVICE_OBJECT DeviceObject,
#endif
IN PAVC_STREAM_EXTENSION pAVCStrmExt
);