📄 dcampkt.c
字号:
ulChannel != pDevExt->IsochChannel) {
//
// Stop tranmission so it will not send data to the old channel,
// which might be "owned" by other device.
//
if(pStrmEx->KSState == KSSTATE_RUN) {
// Disable EnableISO
DCamIsoEnable(pIrb, pDevExt, FALSE);
}
//
// Detach pending packets using the hOldRources and reattached using the new hResource
// Note: incoming SRB_READ is block right now.
// free old resource after all pending reads are detached.
//
if(pDevExt->PendingReadCount > 0) {
Status = DCamReSubmitPacket(hResource, pDevExt, pStrmEx, pDevExt->PendingReadCount);
}
//
// Free "stale" isoch resource
//
if(pDevExt->hResource != hResource) {
DbgMsg2(("DCamReSubmitPacket: Attempt to free hStaleResource %x\n", hResource));
pIrb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
pIrb->Flags = 0;
pIrb->u.IsochFreeResources.hResource = hResource;
Status = DCamSubmitIrpSynch(pDevExt, pIrp, pIrb);
if (Status) {
ERROR_LOG(("\'DCamFreeIsochResource: Error %x while trying to free Isoch resources\n\n", Status));
ASSERT(Status == STATUS_SUCCESS);
}
}
//
// Getting ready to accept callback
//
pDevExt->bStopIsochCallback = FALSE;
//
// Restore to its initial Streaming state
// mainly, programming device.
//
DCamSetKSStateInitialize(pDevExt);
}
KeReleaseMutex(&pStrmEx->hMutex, FALSE);
ExFreePool(pIrb);
IoFreeIrp(pIrp);
}
}
if(Status == STATUS_SUCCESS) {
//
// Set to last saved configuration
//
SetCurrentDevicePropertyValues(pDevExt, (PIRB) Srb->SRBExtension);
}
DbgMsg2(("\'DCamProcessPnpIrp, IRP_MN_BUS_RESET: Done, Status %x\n", Status));
break;
case IRP_MN_QUERY_CAPABILITIES:
ERROR_LOG(("\'SonyDCamProcessPnpIrp: IRP_MN_QUERY_CAPABILITIES: Srb->Status = STATUS_NOT_IMPLEMENTED.\n"));
default:
Srb->Status = STATUS_NOT_IMPLEMENTED;
break;
}
}
VOID
DCamChangePower(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
/*++
Routine Description:
Process chnaging this device's power state.
Arguments:
Srb - Pointer to Stream request block
Return Value:
Nothing
--*/
{
PDCAM_EXTENSION pDevExt;
PSTREAMEX pStrmEx;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(pSrb->Irp);
DEVICE_POWER_STATE DevicePowerState = pSrb->CommandData.DeviceState;
PAGED_CODE();
pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
DbgMsg2(("\'DCamChangePower: pSrb=%x; pDevExt=%x\n", pSrb, pDevExt));
ASSERT(pDevExt != NULL);
if(!pDevExt) {
pSrb->Status = STATUS_INVALID_PARAMETER;
ERROR_LOG(("DCamChangePower: pDevExt is NULL!\n"));
return;
}
pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;
if (pStrmEx ==NULL) {
pSrb->Status = STATUS_SUCCESS;
pDevExt->CurrentPowerState = DevicePowerState;
DbgMsg2(("DCamChangePower: pStrmEx is NULL => Stream is not open. That is Ok!!\n"));
return;
}
//
// We can honor power state change:
//
// D0: device is on and running
// D1,D2: not implemented.
// D3: device is off and not running. Device context is lost.
// Power can be removed from the device.
// when power is back on, we will get a bus reset.
//
// (0) Remove DontSuspendIfStreamsAreRunning from INF
// save current state.
// (1) ->D3, to PAUSE/STOP state (depends on if pending buffers can be kept by its lower driver)
// (2) ->D0, to restore saved state
//
// We can do the above but we do not know at this point
// how our client application react
//
if(IrpStack->MinorFunction == IRP_MN_SET_POWER) {
DbgMsg2(("DCamChangePower: changin power state from %d to %d.\n", pDevExt->CurrentPowerState, DevicePowerState));
pSrb->Status = STATUS_SUCCESS;
if(pDevExt->CurrentPowerState != DevicePowerState) {
switch (DevicePowerState) {
case PowerDeviceD3: // D0->D3: save state, stop streaming and Sleep
if( pDevExt->CurrentPowerState == PowerDeviceD0 ) {
DbgMsg1(("DCamChangePower: Switching from D0 to D3; Save current state.\n"));
// Save current state to be restored when awake
pStrmEx->KSSavedState = pStrmEx->KSState;
}
break;
case PowerDeviceD0: // to Wakeup, restore state and running
if( pDevExt->CurrentPowerState == PowerDeviceD3 ) {
DbgMsg1(("DCamChangePower: Switching from D3 to D0; restore state.\n"));
pStrmEx->KSState = pStrmEx->KSSavedState;
}
break;
// These state are not defined and noe used.
case PowerDeviceD1:
case PowerDeviceD2:
default:
ERROR_LOG(("DCamChangePower: Invalid PowerState %d\n", DevicePowerState));
pSrb->Status = STATUS_INVALID_PARAMETER;
break;
}
}
if(pSrb->Status == STATUS_SUCCESS)
pDevExt->CurrentPowerState = DevicePowerState;
} else {
pSrb->Status = STATUS_NOT_IMPLEMENTED;
}
}
VOID
DCamGetStreamInfo(
IN PHW_STREAM_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Returns the information of all streams that are supported by the driver
Arguments:
Srb - Pointer to Stream request block
Return Value:
Nothing
--*/
{
//
// pick up the pointer to the stream information data structure
//
PIRB pIrb;
PHW_STREAM_HEADER StreamHeader = &(Srb->CommandData.StreamBuffer->StreamHeader);
PDCAM_EXTENSION pDevExt = (PDCAM_EXTENSION) Srb->HwDeviceExtension;
PHW_STREAM_INFORMATION StreamInfo = &(Srb->CommandData.StreamBuffer->StreamInfo);
PAGED_CODE();
pIrb = (PIRB) Srb->SRBExtension;
//
// set number of streams
//
ASSERT (Srb->NumberOfBytesToTransfer >=
sizeof (HW_STREAM_HEADER) +
sizeof (HW_STREAM_INFORMATION));
//
// initialize stream header
//
RtlZeroMemory(StreamHeader,
sizeof (HW_STREAM_HEADER) +
sizeof (HW_STREAM_INFORMATION));
//
// initialize the number of streams supported
//
StreamHeader->NumberOfStreams = 1;
StreamHeader->SizeOfHwStreamInformation = sizeof(HW_STREAM_INFORMATION);
//
// set the device property info
//
StreamHeader->NumDevPropArrayEntries = pDevExt->ulPropSetSupported;
StreamHeader->DevicePropertiesArray = &pDevExt->VideoProcAmpSet;
//
// Initialize the stream structure.
//
// Number of instances field indicates the number of concurrent streams
// of this type the device can support.
//
StreamInfo->NumberOfPossibleInstances = 1;
//
// indicates the direction of data flow for this stream, relative to
// the driver
//
StreamInfo->DataFlow = KSPIN_DATAFLOW_OUT;
//
// dataAccessible - Indicates whether the data is "seen" by the host
// processor.
//
StreamInfo->DataAccessible = TRUE;
//
// Return number of formats and the table.
// These information is collected dynamically.
//
StreamInfo->NumberOfFormatArrayEntries = pDevExt->ModeSupported;
StreamInfo->StreamFormatsArray = &pDevExt->DCamStrmModes[0];
//
// set the property information for the video stream
//
StreamInfo->NumStreamPropArrayEntries = NUMBER_VIDEO_STREAM_PROPERTIES;
StreamInfo->StreamPropertiesArray = (PKSPROPERTY_SET) VideoStreamProperties;
//
// set the pin name and category
//
StreamInfo->Name = (GUID *) &PINNAME_VIDEO_CAPTURE;
StreamInfo->Category = (GUID *) &PINNAME_VIDEO_CAPTURE;
//
// store a pointer to the topology for the device
//
Srb->CommandData.StreamBuffer->StreamHeader.Topology = &Topology;
//
// indicate success
//
Srb->Status = STATUS_SUCCESS;
DbgMsg2(("\'DCamGetStreamInfo: NumFormat %d, StreamFormatArray %x\n",
StreamInfo->NumberOfFormatArrayEntries, StreamInfo->StreamFormatsArray));
}
#define TIME_ROUNDING 1000 // Give it some rounding error of 100microsec
#define TIME_0750FPS (1333333+TIME_ROUNDING) // 1/7.50 * 10,000,000 (unit=100ns)
#define TIME_1500FPS (666666+TIME_ROUNDING) // 1/15.0 * 10,000,000 (unit=100ns) do not round to 666667
#define TIME_3000FPS (333333+TIME_ROUNDING) // 1/30.0 * 10,000,000 (unit=100ns)
NTSTATUS
DCamAllocateIsochResource(
PDCAM_EXTENSION pDevExt,
PIRB Irb,
BOOL bAllocateResource
)
{
PIRP Irp;
CCHAR StackSize;
ULONG ModeIndex;
PSTREAMEX pStrmEx;
DWORD dwAvgTimePerFrame, dwCompression;
ULONG fulSpeed;
NTSTATUS Status = STATUS_SUCCESS;
ASSERT(pDevExt);
pStrmEx = (PSTREAMEX) pDevExt->pStrmEx;
ASSERT(pStrmEx);
DbgMsg2(("\'DCamAllocateIsochResource: enter; pStrmEx %x; pVideoInfo %x\n", pStrmEx, pStrmEx->pVideoInfoHeader));
//
// Now if they're on a YUV4:2:2 format, we've gotta check what
// resolution they want it at, since we support this format
// but in two different resolutions (modes on the camera).
//
// This is the INDEX to the frame rate and resource allocation; see IsochInfoTable.
// 0 : reserved
// 1 : 3.75
// 2 : 7.5
// 3 : 15 (DEFAULT_FRAME_RATE)
// 4 : 30
// 5 : 60 (Not supported for Mode 1 & 3)
dwAvgTimePerFrame = (DWORD) pStrmEx->pVideoInfoHeader->AvgTimePerFrame;
dwCompression = (DWORD) pStrmEx->pVideoInfoHeader->bmiHeader.biCompression;
// Determine the Frame rate
if (dwAvgTimePerFrame > TIME_0750FPS)
pDevExt->FrameRate = 1; // 3.75FPS
else if (dwAvgTimePerFrame > TIME_1500FPS)
pDevExt->FrameRate = 2; // 7.5FPS
else if (dwAvgTimePerFrame > TIME_3000FPS)
pDevExt->FrameRate = 3; // 15 FPS
else
pDevExt->FrameRate = 4; // 30 FPS
DbgMsg2(("\'DCamAllocateIsochResource: FrameRate: %d FPS\n", (1 << (pDevExt->FrameRate-1)) * 15 / 4));
// Determine the Video Mode
switch(dwCompression) {
#ifdef SUPPORT_YUV444
case FOURCC_Y444: // Mode 0
ModeIndex = VMODE0_YUV444;
break;
#endif
case FOURCC_UYVY: // Mode 1 or 3
if (pStrmEx->pVideoInfoHeader->bmiHeader.biWidth == 640 &&
(pStrmEx->pVideoInfoHeader->bmiHeader.biHeight == 480 ||
pStrmEx->pVideoInfoHeader->bmiHeader.biHeight == -480)) {
ModeIndex = VMODE3_YUV422;
// Max frame rate is 15
if(pDevExt->FrameRate > 3)
pDevExt->FrameRate = 3;
} else
ModeIndex = VMODE1_YUV422;
break;
#ifdef SUPPORT_YUV411
case FOURCC_Y411: // Mode 2
ModeIndex = VMODE2_YUV411;
break;
#endif
#ifdef SUPPORT_RGB24
case KS_BI_RGB: // = 0
ModeIndex = VMODE4_RGB24;
// Max frame rate is 15
if(pDevExt->FrameRate > 3)
pDevExt->FrameRate = 3;
break;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -