📄 dcampkt.c
字号:
pDevExt->CurrentModeIndex = ModeIndex;
DbgMsg2(("**IsochAlloc: hResource = %x\n", pDevExt->hResource));
IoFreeIrp(Irp);
return STATUS_SUCCESS;
NoResource_abort:
// Free bandwidth
if(pDevExt->hBandwidth != NULL) {
Irb->FunctionNumber = REQUEST_ISOCH_FREE_BANDWIDTH;
Irb->Flags = 0;
Irb->u.IsochFreeBandwidth.hBandwidth = pDevExt->hBandwidth;
Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
pDevExt->hBandwidth = NULL;
if(Status) {
ERROR_LOG(("DCamAllocateIsochResource: Error %x while trying to free Isoch bandwidth\n", Status));
}
}
// Free channel
if (pDevExt->IsochChannel != ISOCH_ANY_CHANNEL) {
Irb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
Irb->Flags = 0;
Irb->u.IsochFreeChannel.nChannel = pDevExt->IsochChannel;
Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
pDevExt->IsochChannel = ISOCH_ANY_CHANNEL; // Reset it.
if(Status) {
ERROR_LOG(("DCamAllocateIsochResource: Error %x while trying to free Isoch channel\n", Status));
}
}
IoFreeIrp(Irp);
return STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS
DCamFreeIsochResource (
PDCAM_EXTENSION pDevExt,
PIRB Irb,
BOOL bFreeResource
)
/*++
Routine Description:
Free resource allocated in DCamAllocateIsochResource().
Arguments:
Srb - Pointer to Stream request block
Return Value:
Nothing
--*/
{
PIRP Irp;
CCHAR StackSize;
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
DbgMsg2(("\'DCamFreeIsochResource: enter; DevExt=%x, Irb=%x\n", pDevExt, Irb));
ASSERT(pDevExt);
ASSERT(Irb);
if(Irb == 0 ||
pDevExt == 0) {
DbgMsg2(("\'DCamFreeIsochResource: ABORTED!\n"));
return STATUS_SUCCESS;
}
//
// Get an Irp so we can send some free commands down
//
StackSize = pDevExt->BusDeviceObject->StackSize;
Irp = IoAllocateIrp(StackSize, FALSE);
if (!Irp) {
ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to allocate an Irp\n\n", Status));
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// 1. Free Resource
//
if (pDevExt->hResource && bFreeResource) {
DbgMsg2(("\'DCamFreeIsochResource: Attempt to free ->hResource\n"));
Irb->FunctionNumber = REQUEST_ISOCH_FREE_RESOURCES;
Irb->Flags = 0;
Irb->u.IsochFreeResources.hResource = pDevExt->hResource;
Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
pDevExt->hResource = NULL;
if (Status) {
ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to free Isoch resources\n\n", Status));
}
}
//
// 2. Free Channel
//
if (pDevExt->IsochChannel != ISOCH_ANY_CHANNEL) {
DbgMsg2(("\'DCamFreeIsochResource: Attempt to free ->IsochChannel\n"));
Irb->FunctionNumber = REQUEST_ISOCH_FREE_CHANNEL;
Irb->Flags = 0;
Irb->u.IsochFreeChannel.nChannel = pDevExt->IsochChannel;
Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
pDevExt->IsochChannel = ISOCH_ANY_CHANNEL;
if(Status) {
ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to free Isoch channel\n\n", Status));
}
}
//
// 3. Free Bandwidth
//
if (pDevExt->hBandwidth) {
DbgMsg2(("\'DCamFreeIsochResource: Attempt to free ->hBandwidth\n"));
Irb->FunctionNumber = REQUEST_ISOCH_FREE_BANDWIDTH;
Irb->Flags = 0;
Irb->u.IsochFreeBandwidth.hBandwidth = pDevExt->hBandwidth;
Status = DCamSubmitIrpSynch(pDevExt, Irp, Irb);
pDevExt->hBandwidth = NULL;
if (Status) {
ERROR_LOG(("DCamFreeIsochResource: Error %x while trying to free Isoch bandwidth\n", Status));
}
}
DbgMsg2(("\'DCamFreeIsochResource: hResource = %x\n", pDevExt->hResource));
IoFreeIrp(Irp);
return STATUS_SUCCESS;
}
VOID
InitializeStreamExtension(
PDCAM_EXTENSION pDevExt,
PHW_STREAM_OBJECT pStreamObject,
PSTREAMEX pStrmEx
)
{
PAGED_CODE();
pStrmEx->hMasterClock = 0;
pStrmEx->FrameInfo.ExtendedHeaderSize = sizeof(KS_FRAME_INFO);
pStrmEx->FrameInfo.PictureNumber = 0;
pStrmEx->FrameInfo.DropCount = 0;
pStrmEx->FrameInfo.dwFrameFlags = 0;
pStrmEx->FirstFrameTime = 0;
pStrmEx->pVideoInfoHeader = 0;
pStrmEx->KSState = KSSTATE_STOP;
pStrmEx->KSSavedState = KSSTATE_STOP;
pStrmEx->CancelToken = 0;
KeInitializeMutex( &pStrmEx->hMutex, 0); // Level 0 and in Signal state
}
BOOL
DCamDeviceInUse(
PIRB pIrb,
PDCAM_EXTENSION pDevExt
)
/*++
Routine Description:
See if this device is in used.
We check ISO_ENABLE since this is the only register
in a 1394DCam that we can set/get and 99%+ of time
this bit is set by its owner.
Arguments:
pIrb - Pointer to IEEE 1394 Request Block definition (IRB)
pDevExt - this device extension
Return Value:
TRUE: Iso_enable != 0
FALSE: iso_enable == 0
--*/
{
DCamRegArea RegArea;
NTSTATUS status;
LONG lRetries = MAX_READ_REG_RETRIES;
// If a device is removed, it is not available.
if(pDevExt->bDevRemoved)
return TRUE;
do {
RegArea.AsULONG = 0;
status = DCamReadRegister(pIrb, pDevExt, FIELDOFFSET(CAMERA_REGISTER_MAP, IsoEnable), &(RegArea.AsULONG));
#if DBG
if(!NT_SUCCESS(status))
ERROR_LOG(("**** DCamDeviceInUse: Status %x, ISO_ENABLE %x\n", status, RegArea.AsULONG));
#endif
} while (--lRetries > 0 && !NT_SUCCESS(status));
if(NT_SUCCESS(status))
return ((RegArea.AsULONG & ISO_ENABLE_BIT) == ISO_ENABLE_BIT);
// failed to query the device.
return TRUE; // Assume it is in use.
}
VOID
DCamOpenStream(
IN PHW_STREAM_REQUEST_BLOCK pSrb
)
/*++
Routine Description:
Called when an OpenStream Srb request is received
Arguments:
pSrb - Pointer to Stream request block
Return Value:
Nothing
--*/
{
PIRB Irb;
ULONG nSize;
PDCAM_EXTENSION pDevExt;
PSTREAMEX pStrmEx;
PKS_DATAFORMAT_VIDEOINFOHEADER pKSDataFormat =
(PKS_DATAFORMAT_VIDEOINFOHEADER) pSrb->CommandData.OpenFormat;
PKS_VIDEOINFOHEADER pVideoInfoHdrRequested =
&pKSDataFormat->VideoInfoHeader;
PAGED_CODE();
Irb = (PIRB) pSrb->SRBExtension;
pDevExt = (PDCAM_EXTENSION) pSrb->HwDeviceExtension;
pStrmEx = (PSTREAMEX)pSrb->StreamObject->HwStreamExtension;
DbgMsg2(("\'DCamOpenStream: >>> !!! pDevEx %x; pStrmEx %x !!!\n", pDevExt, pStrmEx));
//
// Cache the stream extension.
//
pDevExt->pStrmEx = pStrmEx;
//
// default to success
//
pSrb->Status = STATUS_SUCCESS;
//
// determine which stream number is being opened. This number indicates
// the offset into the array of streaminfo structures that was filled out
// in the AdapterStreamInfo call.
//
// So:
// 0 - Video data from camera
//
switch (pSrb->StreamObject->StreamNumber) {
case 0:
//
// Make sure that this device is not in used
//
if(DCamDeviceInUse(Irb, pDevExt)) {
ERROR_LOG(("Device is in used! Open Stream fail!!\n"));
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_UNSUCCESSFUL;
return;
}
//
// Figure out what format they're trying to open first
//
if (!AdapterVerifyFormat (pDevExt->ModeSupported, pDevExt->DCamStrmModes, pKSDataFormat, pSrb->StreamObject->StreamNumber)) {
pDevExt->pStrmEx = NULL;
ERROR_LOG(("DCamOpenStream: AdapterVerifyFormat failed.\n"));
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
InitializeStreamExtension(pDevExt, pSrb->StreamObject, pStrmEx);
// It should already been freed by DCamCloseStream()
ASSERT(pStrmEx->pVideoInfoHeader == NULL);
ASSERT(pVideoInfoHdrRequested != (PKS_VIDEOINFOHEADER) 0);
//
// use our safe version of KS_SIZE_VIDEOHEADER
//
if (!NT_SUCCESS(RTL_SAFE_KS_SIZE_VIDEOHEADER(pVideoInfoHdrRequested, &nSize))) {
pSrb->Status = STATUS_INTEGER_OVERFLOW;
return;
}
pStrmEx->pVideoInfoHeader = ExAllocatePoolWithTag(NonPagedPool, nSize, 'macd');
if (pStrmEx->pVideoInfoHeader == NULL) {
ERROR_LOG(("DCamOpenStream: ExAllocatePool (->pVideoInfoHeader) failed!\n"));
ASSERT(pStrmEx->pVideoInfoHeader != NULL);
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
// Copy the VIDEOINFOHEADER requested to our storage
RtlCopyMemory(
pStrmEx->pVideoInfoHeader,
pVideoInfoHdrRequested,
nSize);
DbgMsg3(("\'DCamOpenStream: Copied biSizeImage=%d Duration=%ld (100ns)\n",
pStrmEx->pVideoInfoHeader->bmiHeader.biSizeImage, (DWORD) pStrmEx->pVideoInfoHeader->AvgTimePerFrame));
// Allocate ISOCH resource
pSrb->Status = DCamAllocateIsochResource(pDevExt, pSrb->SRBExtension, TRUE);
if (pSrb->Status) {
ERROR_LOG(("DCamOpenStream: !!!! Allocate ISOCH resource failed. CanNOT STREAM!!!!!\n"));
ExFreePool(pStrmEx->pVideoInfoHeader);
pStrmEx->pVideoInfoHeader = NULL;
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INSUFFICIENT_RESOURCES;
return;
}
pSrb->StreamObject->ReceiveDataPacket = (PVOID) DCamReceiveDataPacket;
pSrb->StreamObject->ReceiveControlPacket = (PVOID) DCamReceiveCtrlPacket;
// If bus reset failed and user close the stream and reopen the stream successfully,
// This must be reset !!
if(pDevExt->bDevRemoved || pDevExt->bStopIsochCallback) {
DbgMsg1(("Stream Open successful, reset bDevRemoved and bStopCallback!!\n"));
pDevExt->bStopIsochCallback = FALSE;
pDevExt->bDevRemoved = FALSE;
}
//
// initialize the stream extension data handling information
//
break;
default:
ERROR_LOG(("DCamOpenStream: Hit a non-support pSrb->StreamObject->StreamNumber (%d).\n", pSrb->StreamObject->StreamNumber));
ASSERT(FALSE);
pDevExt->pStrmEx = NULL;
pSrb->Status = STATUS_INVALID_PARAMETER;
return;
}
pSrb->StreamObject->HwClockObject.ClockSupportFlags = 0;
// We don't use DMA.
pSrb->StreamObject->Dma = FALSE;
pSrb->StreamObject->StreamHeaderMediaSpecific = sizeof(KS_FRAME_INFO);
//
// The PIO flag must be set when the mini driver will be accessing the data
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -