📄 capmain.c
字号:
//
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);
DbgLogInfo(("TestCap: Enter AdapterStreamInfo\n"));
//
// 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);
//
// 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;
}
DbgLogInfo(("TestCap: Leave AdapterStreamInfo\n"));
}
/*
** 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
//
AdapterSetProperty (pSrb);
break;
case SRB_PAGING_OUT_DRIVER:
//
// The driver is being paged out
// Disable Interrupts if you have them!
//
DbgLogInfo(("'Testcap: Receiving SRB_PAGING_OUT_DRIVER -- SRB=%x\n", pSrb));
break;
case SRB_CHANGE_POWER_STATE:
//
// Changing the device power state, D0 ... D3
//
DbgLogInfo(("'Testcap: Receiving SRB_CHANGE_POWER_STATE ------ SRB=%x\n", pSrb));
AdapterPowerState(pSrb);
break;
case SRB_INITIALIZATION_COMPLETE:
//
// Stream class has finished initialization.
// Now create DShow Medium interface BLOBs.
// This needs to be done at low priority since it uses the registry
//
DbgLogInfo(("'Testcap: Receiving SRB_INITIALIZATION_COMPLETE-- SRB=%x\n", pSrb));
break;
case SRB_UNKNOWN_DEVICE_COMMAND:
default:
//
// this is a request that we do not understand. Indicate invalid
// command and complete the request
//
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
//
// Indicate back to the Stream Class that we're done with this SRB
//
CompleteDeviceSRB (pSrb);
//
// See if there's anything else on the queue
//
Busy = RemoveFromListIfAvailable (
&pSrb,
&pHwDevExt->AdapterSpinLock,
&pHwDevExt->ProcessingAdapterSRB,
&pHwDevExt->AdapterSRBList);
if (!Busy) {
break;
}
} // end of while there's anything in the queue
}
/*
** AdapterCancelPacket ()
**
** Request to cancel a packet that is currently in process in the minidriver
**
** Arguments:
**
** pSrb - pointer to request packet to cancel
**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -