📄 capmain.c
字号:
// the stream extension structure is allocated by the stream class driver
//
PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
int StreamNumber = pSrb->StreamObject->StreamNumber;
PKSDATAFORMAT pKSDataFormat = pSrb->CommandData.OpenFormat;
RtlZeroMemory(pStrmEx, sizeof(STREAMEX));
DbgLogInfo(("TestCap: ------- ADAPTEROPENSTREAM ------- StreamNumber=%d\n", StreamNumber));
//
// check that the stream index requested isn't too high
// or that the maximum number of instances hasn't been exceeded
//
if (StreamNumber >= DRIVER_STREAM_COUNT || StreamNumber < 0) {
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
//
// Check that we haven't exceeded the instance count for this stream
//
if (pHwDevExt->ActualInstances[StreamNumber] >=
Streams[StreamNumber].hwStreamInfo.NumberOfPossibleInstances) {
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
//
// Check the validity of the format being requested
//
if (!AdapterVerifyFormat (pKSDataFormat, StreamNumber)) {
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
//
// And set the format for the stream
//
if (!VideoSetFormat (pSrb)) {
return;
}
ASSERT (pHwDevExt->pStrmEx [StreamNumber] == NULL);
// Maintain an array of all the StreamEx structures in the HwDevExt
// so that we can cancel IRPs from any stream
pHwDevExt->pStrmEx [StreamNumber] = (PSTREAMX) pStrmEx;
// Set up pointers to the handlers for the stream data and control handlers
pSrb->StreamObject->ReceiveDataPacket =
(PVOID) Streams[StreamNumber].hwStreamObject.ReceiveDataPacket;
pSrb->StreamObject->ReceiveControlPacket =
(PVOID) Streams[StreamNumber].hwStreamObject.ReceiveControlPacket;
//
// The DMA flag must be set when the device will be performing DMA directly
// to the data buffer addresses passed in to the ReceiceDataPacket routines.
//
pSrb->StreamObject->Dma = Streams[StreamNumber].hwStreamObject.Dma;
//
// The PIO flag must be set when the mini driver will be accessing the data
// buffers passed in using logical addressing
//
pSrb->StreamObject->Pio = Streams[StreamNumber].hwStreamObject.Pio;
//
// How many extra bytes will be passed up from the driver for each frame?
//
pSrb->StreamObject->StreamHeaderMediaSpecific =
Streams[StreamNumber].hwStreamObject.StreamHeaderMediaSpecific;
pSrb->StreamObject->StreamHeaderWorkspace =
Streams[StreamNumber].hwStreamObject.StreamHeaderWorkspace;
//
// Indicate the clock support available on this stream
//
pSrb->StreamObject->HwClockObject =
Streams[StreamNumber].hwStreamObject.HwClockObject;
//
// Increment the instance count on this stream
//
pHwDevExt->ActualInstances[StreamNumber]++;
// Retain a private copy of the HwDevExt and StreamObject in the stream extension
// so we can use a timer
pStrmEx->pHwDevExt = pHwDevExt; // For timer use
pStrmEx->pStreamObject = pSrb->StreamObject; // For timer use
// Initialize the compression settings
// These may have been changed from the default values in the HwDevExt
// before the stream was opened
pStrmEx->CompressionSettings.CompressionKeyFrameRate =
pHwDevExt->CompressionSettings.CompressionKeyFrameRate;
pStrmEx->CompressionSettings.CompressionPFramesPerKeyFrame =
pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame;
pStrmEx->CompressionSettings.CompressionQuality =
pHwDevExt->CompressionSettings.CompressionQuality;
// Init VideoControl properties
pStrmEx->VideoControlMode = pHwDevExt->VideoControlMode;
// Init VBI variables
pStrmEx->SentVBIInfoHeader = 0;
DbgLogInfo(("TestCap: AdapterOpenStream Exit\n"));
}
/*
** AdapterCloseStream()
**
** Close the requested data stream.
**
** Note that a stream could be closed arbitrarily in the midst of streaming
** if a user mode app crashes. Therefore, you must release all outstanding
** resources, disable interrupts, complete all pending SRBs, and put the
** stream back into a quiescent condition.
**
** Arguments:
**
** pSrb the request block requesting to close the stream
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterCloseStream (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PSTREAMEX pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
int StreamNumber = pSrb->StreamObject->StreamNumber;
PKSDATAFORMAT pKSDataFormat = pSrb->CommandData.OpenFormat;
KS_VIDEOINFOHEADER *pVideoInfoHdr = pStrmEx->pVideoInfoHeader;
DbgLogInfo(("TestCap: -------- ADAPTERCLOSESTREAM ------ StreamNumber=%d\n", StreamNumber));
if (pHwDevExt->StreamSRBListSize > 0) {
VideoQueueCancelAllSRBs (pStrmEx);
DbgLogError(("TestCap: Outstanding SRBs at stream close!!!\n"));
}
pHwDevExt->ActualInstances[StreamNumber]--;
ASSERT (pHwDevExt->pStrmEx [StreamNumber] != 0);
pHwDevExt->pStrmEx [StreamNumber] = 0;
//
// the minidriver should free any resources that were allocate at
// open stream time etc.
//
// Free the variable length VIDEOINFOHEADER
if (pVideoInfoHdr) {
ExFreePool(pVideoInfoHdr);
pStrmEx->pVideoInfoHeader = NULL;
}
// Make sure we no longer reference the clock
pStrmEx->hMasterClock = NULL;
// Make sure the state is reset to stopped,
pStrmEx->KSState = KSSTATE_STOP;
}
/*
** AdapterStreamInfo()
**
** Returns the information of all streams that are supported by the
** mini-driver
**
** Arguments:
**
** pSrb - Pointer to the STREAM_REQUEST_BLOCK
** pSrb->HwDeviceExtension - will be the hardware device extension for
** as initialised in HwInitialise
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterStreamInfo (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
int j;
PHW_DEVICE_EXTENSION pHwDevExt =
((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
//
// pick up the pointer to header which preceeds the stream info structs
//
PHW_STREAM_HEADER pstrhdr =
(PHW_STREAM_HEADER)&(pSrb->CommandData.StreamBuffer->StreamHeader);
//
// pick up the pointer to the array of stream information data structures
//
PHW_STREAM_INFORMATION pstrinfo =
(PHW_STREAM_INFORMATION)&(pSrb->CommandData.StreamBuffer->StreamInfo);
//
// verify that the buffer is large enough to hold our return data
//
DEBUG_ASSERT (pSrb->NumberOfBytesToTransfer >=
sizeof (HW_STREAM_HEADER) +
sizeof (HW_STREAM_INFORMATION) * DRIVER_STREAM_COUNT);
// Ugliness. To allow mulitple instances, modify the pointer to the
// AnalogVideoMedium and save it in our device extension
Streams[STREAM_AnalogVideoInput].hwStreamInfo.Mediums =
&pHwDevExt->AnalogVideoInputMedium;
// pHwDevExt->AnalogVideoInputMedium = CrossbarMediums[9];
// pHwDevExt->AnalogVideoInputMedium.Id = pHwDevExt->DriverMediumInstanceCount;
//
// Set the header
//
StreamHeader.NumDevPropArrayEntries = NUMBER_OF_ADAPTER_PROPERTY_SETS;
StreamHeader.DevicePropertiesArray = (PKSPROPERTY_SET) AdapterPropertyTable;
*pstrhdr = StreamHeader;
//
// stuff the contents of each HW_STREAM_INFORMATION struct
//
for (j = 0; j < DRIVER_STREAM_COUNT; j++) {
*pstrinfo++ = Streams[j].hwStreamInfo;
}
}
/*
** AdapterReceivePacket()
**
** Main entry point for receiving adapter based request SRBs. This routine
** will always be called at Passive level.
**
** Note: This is an asyncronous entry point. The request does not necessarily
** complete on return from this function, the request only completes when a
** StreamClassDeviceNotification on this request block, of type
** DeviceRequestComplete, is issued.
**
** Arguments:
**
** pSrb - Pointer to the STREAM_REQUEST_BLOCK
** pSrb->HwDeviceExtension - will be the hardware device extension for
** as initialised in HwInitialise
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterReceivePacket(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
BOOL Busy;
DEBUG_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
DbgLogTrace(("TestCap: Receiving Adapter SRB %8x, %x\n", pSrb, pSrb->Command));
// The very first time through, we need to initialize the adapter spinlock
// and queue
if (!pHwDevExt->AdapterQueueInitialized) {
InitializeListHead (&pHwDevExt->AdapterSRBList);
KeInitializeSpinLock (&pHwDevExt->AdapterSpinLock);
pHwDevExt->AdapterQueueInitialized = TRUE;
pHwDevExt->ProcessingAdapterSRB = FALSE;
}
//
// If we're already processing an SRB, add it to the queue
//
Busy = AddToListIfBusy (
pSrb,
&pHwDevExt->AdapterSpinLock,
&pHwDevExt->ProcessingAdapterSRB,
&pHwDevExt->AdapterSRBList);
if (Busy) {
return;
}
//
// This will run until the queue is empty
//
while (TRUE) {
//
// Assume success
//
pSrb->Status = STATUS_SUCCESS;
//
// determine the type of packet.
//
switch (pSrb->Command)
{
case SRB_INITIALIZE_DEVICE:
// open the device
HwInitialize(pSrb);
break;
case SRB_UNINITIALIZE_DEVICE:
// close the device.
HwUnInitialize(pSrb);
break;
case SRB_OPEN_STREAM:
// open a stream
AdapterOpenStream(pSrb);
break;
case SRB_CLOSE_STREAM:
// close a stream
AdapterCloseStream(pSrb);
break;
case SRB_GET_STREAM_INFO:
//
// return a block describing all the streams
//
AdapterStreamInfo(pSrb);
break;
case SRB_GET_DATA_INTERSECTION:
//
// Return a format, given a range
//
AdapterFormatFromRange(pSrb);
break;
case SRB_OPEN_DEVICE_INSTANCE:
case SRB_CLOSE_DEVICE_INSTANCE:
//
// We should never get these since this is a single instance device
//
TRAP;
pSrb->Status = STATUS_NOT_IMPLEMENTED;
break;
case SRB_GET_DEVICE_PROPERTY:
//
// Get adapter wide properties
//
AdapterGetProperty (pSrb);
break;
case SRB_SET_DEVICE_PROPERTY:
//
// Set adapter wide properties
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -