?? capmain.c
字號:
//==========================================================================;
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1992 - 1999 Microsoft Corporation. All Rights Reserved.
//
//==========================================================================;
#include "strmini.h"
#include "ksmedia.h"
#include "capmain.h"
#include "mediums.h"
#include "capstrm.h"
#include "capprop.h"
#include "capdebug.h"
// The only global used by this driver. It is used to keep track of the instance count of
// the number of times the driver is loaded. This is used to create unique Mediums so that
// the correct capture, crossbar, tuner, and tvaudio filters all get connected together.
UINT GlobalDriverMediumInstanceCount = 0;
// Debug Logging
// 0 = Errors only
// 1 = Info, stream state changes, stream open close
// 2 = Verbose trace
ULONG gDebugLevel = 2;
/*
** DriverEntry()
**
** This routine is called when the driver is first loaded by PnP.
** It in turn, calls upon the stream class to perform registration services.
**
** Arguments:
**
** DriverObject -
** Driver object for this driver
**
** RegistryPath -
** Registry path string for this driver's key
**
** Returns:
**
** Results of StreamClassRegisterAdapter()
**
** Side Effects: none
*/
ULONG
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
HW_INITIALIZATION_DATA HwInitData;
ULONG ReturnValue;
DbgLogInfo(("TestCap: DriverEntry\n"));
RtlZeroMemory(&HwInitData, sizeof(HwInitData));
HwInitData.HwInitializationDataSize = sizeof(HwInitData);
//
// Set the Adapter entry points for the driver
//
HwInitData.HwInterrupt = NULL; // HwInterrupt;
HwInitData.HwReceivePacket = AdapterReceivePacket;
HwInitData.HwCancelPacket = AdapterCancelPacket;
HwInitData.HwRequestTimeoutHandler = AdapterTimeoutPacket;
HwInitData.DeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
HwInitData.PerRequestExtensionSize = sizeof(SRB_EXTENSION);
HwInitData.FilterInstanceExtensionSize = 0;
HwInitData.PerStreamExtensionSize = sizeof(STREAMEX);
HwInitData.BusMasterDMA = FALSE;
HwInitData.Dma24BitAddresses = FALSE;
HwInitData.BufferAlignment = 3;
HwInitData.DmaBufferSize = 0;
// Don't rely on the stream class using raised IRQL to synchronize
// execution. This single paramter most affects the overall structure
// of the driver.
HwInitData.TurnOffSynchronization = TRUE;
ReturnValue = StreamClassRegisterAdapter(DriverObject, RegistryPath, &HwInitData);
DbgLogInfo(("Testcap: StreamClassRegisterAdapter = %x\n", ReturnValue));
return ReturnValue;
}
//==========================================================================;
// Adapter Based Request Handling Routines
//==========================================================================;
/*
** HwInitialize()
**
** This routine is called when an SRB_INITIALIZE_DEVICE request is received
**
** Arguments:
**
** pSrb - pointer to stream request block for the Initialize command
**
** Returns:
**
** Side Effects: none
*/
BOOLEAN
STREAMAPI
HwInitialize (
IN OUT PHW_STREAM_REQUEST_BLOCK pSrb
)
{
STREAM_PHYSICAL_ADDRESS adr;
ULONG Size;
PUCHAR pDmaBuf;
int j;
PPORT_CONFIGURATION_INFORMATION ConfigInfo = pSrb->CommandData.ConfigInfo;
PHW_DEVICE_EXTENSION pHwDevExt =
(PHW_DEVICE_EXTENSION)ConfigInfo->HwDeviceExtension;
DbgLogInfo(("Testcap: HwInitialize()\n"));
if (ConfigInfo->NumberOfAccessRanges != 0) {
DbgLogError(("Testcap: illegal config info\n"));
pSrb->Status = STATUS_NO_SUCH_DEVICE;
return (FALSE);
}
DbgLogInfo(("TestCap: Number of access ranges = %lx\n", ConfigInfo->NumberOfAccessRanges));
DbgLogInfo(("TestCap: Memory Range = %lx\n", pHwDevExt->ioBaseLocal));
DbgLogInfo(("TestCap: IRQ = %lx\n", ConfigInfo->BusInterruptLevel));
if (ConfigInfo->NumberOfAccessRanges != 0) {
pHwDevExt->ioBaseLocal
= (PULONG)(ULONG_PTR) (ConfigInfo->AccessRanges[0].RangeStart.LowPart);
}
pHwDevExt->Irq = (USHORT)(ConfigInfo->BusInterruptLevel);
ConfigInfo->StreamDescriptorSize = sizeof (HW_STREAM_HEADER) +
DRIVER_STREAM_COUNT * sizeof (HW_STREAM_INFORMATION);
pDmaBuf = StreamClassGetDmaBuffer(pHwDevExt);
adr = StreamClassGetPhysicalAddress(pHwDevExt,
NULL, pDmaBuf, DmaBuffer, &Size);
// Init VideoProcAmp properties
pHwDevExt->Brightness = BrightnessDefault;
pHwDevExt->BrightnessFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
pHwDevExt->Contrast = ContrastDefault;
pHwDevExt->ContrastFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_AUTO;
pHwDevExt->ColorEnable = ColorEnableDefault;
pHwDevExt->ColorEnableFlags = KSPROPERTY_VIDEOPROCAMP_FLAGS_MANUAL;
// Init CameraControl properties
pHwDevExt->Focus = FocusDefault;
pHwDevExt->FocusFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
pHwDevExt->Zoom = ZoomDefault;
pHwDevExt->ZoomFlags = KSPROPERTY_CAMERACONTROL_FLAGS_AUTO;
// Init VideoControl properties
pHwDevExt->VideoControlMode = 0;
// Init VideoCompression properties
pHwDevExt->CompressionSettings.CompressionKeyFrameRate = 15;
pHwDevExt->CompressionSettings.CompressionPFramesPerKeyFrame = 3;
pHwDevExt->CompressionSettings.CompressionQuality = 5000;
pHwDevExt->PDO = ConfigInfo->RealPhysicalDeviceObject;
DbgLogInfo(("TestCap: Physical Device Object = %lx\n", pHwDevExt->PDO));
for (j = 0; j < MAX_TESTCAP_STREAMS; j++){
// For each stream, maintain a separate queue for data and control
InitializeListHead (&pHwDevExt->StreamSRBList[j]);
InitializeListHead (&pHwDevExt->StreamControlSRBList[j]);
KeInitializeSpinLock (&pHwDevExt->StreamSRBSpinLock[j]);
pHwDevExt->StreamSRBListSize[j] = 0;
}
// Init ProtectionStatus
pHwDevExt->ProtectionStatus = 0;
// The following allows multiple instance of identical hardware
// to be installed. GlobalDriverMediumInstanceCount is set in the Medium.Id field.
pHwDevExt->DriverMediumInstanceCount = GlobalDriverMediumInstanceCount++;
DbgLogInfo(("TestCap: Exit, HwInitialize()\n"));
pSrb->Status = STATUS_SUCCESS;
return (TRUE);
}
/*
** HwUnInitialize()
**
** This routine is called when an SRB_UNINITIALIZE_DEVICE request is received
**
** Arguments:
**
** pSrb - pointer to stream request block for the UnInitialize command
**
** Returns:
**
** Side Effects: none
*/
BOOLEAN
STREAMAPI
HwUnInitialize (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
pSrb->Status = STATUS_SUCCESS;
return TRUE;
}
/*
** AdapterPowerState()
**
** This routine is called when an SRB_CHANGE_POWER_STATE request is received
**
** Arguments:
**
** pSrb - pointer to stream request block for the Change Power state command
**
** Returns:
**
** Side Effects: none
*/
BOOLEAN
STREAMAPI
AdapterPowerState (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
pHwDevExt->DeviceState = pSrb->CommandData.DeviceState;
return TRUE;
}
/*
** AdapterOpenStream()
**
** This routine is called when an OpenStream SRB request is received.
** A stream is identified by a stream number, which indexes an array
** of KSDATARANGE structures. The particular KSDATAFORMAT format to
** be used is also passed in, which should be verified for validity.
**
** Arguments:
**
** pSrb - pointer to stream request block for the Open command
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterOpenStream (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
//
// 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -