📄 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 = 0;
/*
** 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 Crossbar properties
pHwDevExt->VideoInputConnected = 0; // TvTuner video is the default
pHwDevExt->AudioInputConnected = 5; // TvTuner audio is the default
// 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 TvTuner properties
pHwDevExt->TunerMode = KSPROPERTY_TUNER_MODE_TV;
pHwDevExt->Channel = 4;
pHwDevExt->TunerInput = 0;
pHwDevExt->Busy = 0;
// Init TvAudio properties
pHwDevExt->TVAudioMode = KS_TVAUDIO_MODE_MONO |
KS_TVAUDIO_MODE_LANG_A ;
// Init AnalogVideoDecoder properties
pHwDevExt->VideoDecoderVideoStandard = KS_AnalogVideo_NTSC_M;
pHwDevExt->VideoDecoderOutputEnable = FALSE;
pHwDevExt->VideoDecoderVCRTiming = FALSE;
// 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++;
AdapterSetInstance (pSrb);
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;
}
/*
** AdapterSetInstance()
**
** This routine is called to set all of the Medium instance fields
**
** Arguments:
**
** pSrb - pointer to stream request block
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterSetInstance (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
int j;
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
// Use our HwDevExt as the instance data on the Mediums
// This allows multiple instances to be uniquely identified and
// connected. The value used in .Id is not important, only that
// it is unique for each hardware connection
for (j = 0; j < SIZEOF_ARRAY (TVTunerMediums); j++) {
TVTunerMediums[j].Id = pHwDevExt->DriverMediumInstanceCount;
}
for (j = 0; j < SIZEOF_ARRAY (TVAudioMediums); j++) {
TVAudioMediums[j].Id = pHwDevExt->DriverMediumInstanceCount;
}
for (j = 0; j < SIZEOF_ARRAY (CrossbarMediums); j++) {
CrossbarMediums[j].Id = pHwDevExt->DriverMediumInstanceCount;
}
for (j = 0; j < SIZEOF_ARRAY (CaptureMediums); j++) {
CaptureMediums[j].Id = pHwDevExt->DriverMediumInstanceCount;
}
pHwDevExt->AnalogVideoInputMedium = CaptureMediums[2];
}
/*
** AdapterCompleteInitialization()
**
** This routine is called when an SRB_COMPLETE_INITIALIZATION request is received
**
** Arguments:
**
** pSrb - pointer to stream request block
**
** Returns:
**
** Side Effects: none
*/
VOID
STREAMAPI
AdapterCompleteInitialization (
PHW_STREAM_REQUEST_BLOCK pSrb
)
{
NTSTATUS Status;
PHW_DEVICE_EXTENSION pHwDevExt = ((PHW_DEVICE_EXTENSION)pSrb->HwDeviceExtension);
KIRQL KIrql;
KIrql = KeGetCurrentIrql();
// Create the Registry blobs that DShow uses to create
// graphs via Mediums
// Register the TVTuner
Status = StreamClassRegisterFilterWithNoKSPins (
pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_TVTUNER, // IN GUID * InterfaceClassGUID,
SIZEOF_ARRAY (TVTunerMediums), // IN ULONG PinCount,
TVTunerPinDirection, // IN ULONG * Flags,
TVTunerMediums, // IN KSPIN_MEDIUM * MediumList,
NULL // IN GUID * CategoryList
);
// Register the Crossbar
Status = StreamClassRegisterFilterWithNoKSPins (
pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_CROSSBAR, // IN GUID * InterfaceClassGUID,
SIZEOF_ARRAY (CrossbarMediums), // IN ULONG PinCount,
CrossbarPinDirection, // IN ULONG * Flags,
CrossbarMediums, // IN KSPIN_MEDIUM * MediumList,
NULL // IN GUID * CategoryList
);
// Register the TVAudio decoder
Status = StreamClassRegisterFilterWithNoKSPins (
pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_TVAUDIO, // IN GUID * InterfaceClassGUID,
SIZEOF_ARRAY (TVAudioMediums), // IN ULONG PinCount,
TVAudioPinDirection, // IN ULONG * Flags,
TVAudioMediums, // IN KSPIN_MEDIUM * MediumList,
NULL // IN GUID * CategoryList
);
// Register the Capture filter
// Note: This should be done automatically be MSKsSrv.sys,
// when that component comes on line (if ever) ...
Status = StreamClassRegisterFilterWithNoKSPins (
pHwDevExt->PDO, // IN PDEVICE_OBJECT DeviceObject,
&KSCATEGORY_CAPTURE, // IN GUID * InterfaceClassGUID,
SIZEOF_ARRAY (CaptureMediums), // IN ULONG PinCount,
CapturePinDirection, // IN ULONG * Flags,
CaptureMediums, // IN KSPIN_MEDIUM * MediumList,
NULL // IN GUID * CategoryList
);
}
/*
** 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
)
{
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -