📄 bdatunerfilter.cpp
字号:
/*+++ *******************************************************************\
*
* Copyright and Disclaimer:
*
* ---------------------------------------------------------------
* This software is provided "AS IS" without warranty of any kind,
* either expressed or implied, including but not limited to the
* implied warranties of noninfringement, merchantability and/or
* fitness for a particular purpose.
* ---------------------------------------------------------------
*
* Copyright (c) 2008 Conexant Systems, Inc.
* All rights reserved.
*
\******************************************************************* ---*/
#include "bdaTunerFilter.h"
#include "Bda_Descriptors.h"
#include "device.h"
#include "miscfuncs.h"
#include "debug.h"
#include "IBdaTuner.h"
#include "RegistryAccess.h"
#include "CrossbarProp.h"
#include "cusbintf.h"
#include "Polaris_GPIOPin.h"
#include "GenSiTuner.h"
#include "ITunerProperties.h"
/////////////////////////////////////////////////////////////////////////////////////////
BdaTunerFilter::BdaTunerFilter(Device* p_device) :
_bda_change_state(BDA_CHANGES_COMPLETE),
_tuner_is_initialized(FALSE),
_freq_initialized(FALSE),
_p_device(p_device)
{
//Initialize the current and pending frequency settings.
_current_freq.frequency = 0;
_current_freq.frequency_multiplier = 1;
_current_freq.channel_bandwidth = 0;
_pending_freq.frequency = 0;
_pending_freq.frequency_multiplier = 1;
_pending_freq.channel_bandwidth = 0;
_p_tuner = _p_device->getBdaTuner();
if(!_p_device->isRunning())
{
InitBdaDevices();
}
}
/////////////////////////////////////////////////////////////////////////////////////////
BdaTunerFilter::~BdaTunerFilter()
{
DbgLogTrace((__FUNCTION__));
if(_p_tuner && !_p_device->isRunning())
{
_p_tuner->bdaTuner_powerDown();
}
}
VOID BdaTunerFilter::InitBdaDevices()
{
if(_p_device==NULL)
return;
USHORT revID=_p_device->getRevID();
if(revID == POLARIS_REVID_T0)
{
_p_device->setUSBConfiguration(VIDEO_INPUT_BDA);
}
else if(revID>=POLARIS_REVID_A0 )
{
//For A0
if((_p_device->getUSBType() == USB_BUS_POWER)) //bus power
{
_p_device->setPowerMode(POLARIS_AVMODE_DIGITAL);
}
}
// AGC mux for Demod/Analog
// 0 - Demod, 1 - Analog
PolarisGPIOPin* pGPIOpin = _p_device->getGPIOPin();
if(pGPIOpin)
{
// Switch to Demod
pGPIOpin->SetGpioPinLogicValue(pGPIOpin->getAGCAnalogDigitalMuxSelectGPIOBit(), 0);
}
//Tuner must be re-initialized to accompany with demodulator
//Otherwise, tuner will not able to lock channel once again for next TS BDA filter graph
//This solutions is the workaround way. It will be replaced by makeing _p_device->resetAnalogTuner() really
//taken effect for Sidewinder initialization in Altair lib.
if(revID>=POLARIS_REVID_A0)
{
if(_p_device->getUSBType()==USB_BUS_POWER)
{
ITunerProperties * p_tuner_prop=_p_device->getTunerProperties();
if(p_tuner_prop)
{
ITuner *p_analog_tuner=p_tuner_prop->getTuner();
if(p_analog_tuner)
{
p_analog_tuner->Initialize();
}
}
}
}
if(_p_tuner)
{
_p_tuner->bdaTuner_powerUp();
_p_device->setBdaTunerPowerUpState(FALSE);
}
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::static_Create(PKSFILTER p_ks_filter,
PIRP p_irp)
{
Device* p_device = getDevice(p_irp);
p_ks_filter->Context = new BdaTunerFilter(p_device);
if( !p_ks_filter->Context )
{
return STATUS_INSUFFICIENT_RESOURCES;
}
NTSTATUS Status = BdaInitFilter(p_ks_filter,(BDA_FILTER_TEMPLATE *)p_device->getFilterTemplate());
if( !NT_SUCCESS(Status) )
{
DbgLogError(("BdaTunerFilter: static_Create : BdaInitFilter failed\n"));
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::static_Close(PKSFILTER p_ks_filter,
PIRP p_irp)
{
delete reinterpret_cast<BdaTunerFilter*>( p_ks_filter->Context );
p_ks_filter->Context = NULL;
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::static_RegisterFilter(KSDEVICE* p_ks_device, DWORD medium_id)
{
KSPIN_MEDIUM antenna_pin_medium = {0, 0, 0};
const ULONG pin_count = 2;
//Create an array of mediums
KSPIN_MEDIUM mediums[pin_count];
mediums[BDA_PIN_ANTENNA] = antenna_pin_medium;
mediums[BDA_PIN_TRANSPORT] = g_bda_transport_pin_medium;
mediums[BDA_PIN_TRANSPORT].Id = medium_id;
//Create an array of pin directions
const BOOL INPUT_PIN = FALSE;
const BOOL OUTPUT_PIN = TRUE;
BOOL pin_directions[pin_count] =
{
INPUT_PIN,
OUTPUT_PIN
};
return KsRegisterFilterWithNoKSPins(
p_ks_device->PhysicalDeviceObject,
&KSCATEGORY_BDA_NETWORK_TUNER,
pin_count,
pin_directions,
mediums,
NULL);
}
//////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::AllocateFilterDescriptorForMediums
(
IN KSFILTER_DESCRIPTOR FilterDescriptor,
IN KSOBJECT_BAG ObjectBag,
IN DWORD medium_id,
OUT PKSFILTER_DESCRIPTOR *ppFilterDescriptor
)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
// Dynamically allocate filter descriptor.
*ppFilterDescriptor = (PKSFILTER_DESCRIPTOR)
ExAllocatePoolWithTag(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR), 'txnC');
if (!*ppFilterDescriptor)
{
DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Insufficient memory\n"));
ntStatus = STATUS_NO_MEMORY;
return ntStatus;
}
ntStatus = KsAddItemToObjectBag(ObjectBag, *ppFilterDescriptor, NULL);
if (!NT_SUCCESS(ntStatus))
{
DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Failed to add filter descriptor to object bag\n"));
ExFreePool(*ppFilterDescriptor);
return ntStatus;
}
// Use the values from the original descriptor by default (even if they are static)
// Only those fields will be reallocated that need to have updated values - in this
// case the pin descriptors and the mediums
**ppFilterDescriptor = FilterDescriptor;
if (FilterDescriptor.PinDescriptorsCount == 0)
{
return STATUS_SUCCESS;
}
// Allocate the pin descriptor list dynamically
KSPIN_DESCRIPTOR_EX* pPinDescriptorsEx =
(KSPIN_DESCRIPTOR_EX *) ExAllocatePoolWithTag(NonPagedPool,
FilterDescriptor.PinDescriptorSize * FilterDescriptor.PinDescriptorsCount,
'txnC');
if (!pPinDescriptorsEx)
{
DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Insufficient memory for pin descriptors\n"));
ntStatus = STATUS_NO_MEMORY;
return ntStatus;
}
ntStatus = KsAddItemToObjectBag(ObjectBag, pPinDescriptorsEx, NULL);
if (!NT_SUCCESS(ntStatus))
{
DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Failed to add pin descriptors to object bag\n"));
ExFreePool(pPinDescriptorsEx);
return ntStatus;
}
// Copy default values over even if the default pointers are static. Update/reallocate
// only required fields - namely the mediums
RtlCopyMemory(pPinDescriptorsEx, FilterDescriptor.PinDescriptors,
FilterDescriptor.PinDescriptorSize * FilterDescriptor.PinDescriptorsCount);
// Update/reallocate the relevant fields - the mediums
for (unsigned int i = 0; i < FilterDescriptor.PinDescriptorsCount; i++)
{
// The size of the pin descriptors is specified in the filter descriptor
KSPIN_DESCRIPTOR_EX* pCurrentPinDescriptorEx =
(KSPIN_DESCRIPTOR_EX *) (((BYTE *)pPinDescriptorsEx) + i * FilterDescriptor.PinDescriptorSize);
KSPIN_DESCRIPTOR* pPinDescriptor = &pCurrentPinDescriptorEx->PinDescriptor;
KSPIN_MEDIUM *pPinMediums = NULL;
// If this pin has no mediums continue
if (pPinDescriptor->MediumsCount == 0) {
continue;
}
// Allocate memory for the pin mediums
pPinMediums = (KSPIN_MEDIUM *)ExAllocatePoolWithTag(NonPagedPool,
sizeof(KSPIN_MEDIUM) * pPinDescriptor->MediumsCount,
'txnC');
if (!pPinMediums)
{
DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Insufficient memory for pin mediums\n"));
ntStatus = STATUS_NO_MEMORY;
return ntStatus;
}
ntStatus = KsAddItemToObjectBag(ObjectBag, pPinMediums, NULL);
if (!NT_SUCCESS(ntStatus))
{
DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Failed to add pin mediums to object bag\n"));
ExFreePool(pPinMediums);
return ntStatus;
}
// Copy over all the mediums. The Medium.Set guid is the same across all instances.
RtlCopyMemory(pPinMediums, pPinDescriptor->Mediums,
sizeof(KSPIN_MEDIUM) * pPinDescriptor->MediumsCount);
for (unsigned int j = 0; j < pPinDescriptor->MediumsCount; j++)
{
// The core of this function. Update the Medium.Id
// 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 example, one could
// use serial numbers to generate such a unique Id.
((KSPIN_MEDIUM *)pPinMediums)[j].Id = medium_id;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -