📄 itunerproperties.cpp
字号:
if(!p_properties)
{
return STATUS_UNSUCCESSFUL;
}
//TODO
/*
// set activity state
p_device->setCfpmActivityState(analogTuner_pwr_block,true);
// verify whether the device is powered up or not
p_device->setCfpmPowerMode(analogTuner_pwr_block, WAKEUP);
if ((!p_properties->_p_device->IsBoardCombo()) &&
(p_properties->_p_device->getCurrentGraphMode() == GRAPH_MODE_DIGITAL)
)
{
// set activity state
p_device->setCfpmActivityState(analogTuner_pwr_block,false);
DbgLogWarn(("ITunerProperties::static_setFrequency : Tuner already acquired by BDA !!!\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
DbgLogInfo((
"static_setFrequency : Received tune request. Frequency = %d, flags = %x\n",
p_request->Frequency,
p_request->TuningFlags));
if(!(p_properties->_p_device->DeviceActive()))
{
// set activity state
p_device->setCfpmActivityState(analogTuner_pwr_block,false);
DbgLogWarn(("ITunerProperties::static_setFrequency : Device not Active !!!\n"));
return STATUS_DEVICE_NOT_READY;
}
*/
NTSTATUS status = p_properties->setFrequency(
p_request->Frequency,
p_request->Country,
p_request->TuningFlags);
// set activity state
//TODO p_device->setCfpmActivityState(analogTuner_pwr_block,false);
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
//ITunerProperties::static_getInput
//
// Static DDK handler for KSPROPERTY_TUNER_INPUT
//
// Returns the current tuner input, stored in the base class.
//
NTSTATUS ITunerProperties::static_getInput(
PIRP p_irp,
PKSPROPERTY_TUNER_INPUT_S p_request,
PKSPROPERTY_TUNER_INPUT_S p_data)
{
//Get the filter
PKSFILTER p_filter = KsGetFilterFromIrp(p_irp);
if(!p_filter)
{
return STATUS_UNSUCCESSFUL;
}
PKSDEVICE p_ks_device = KsFilterGetDevice(p_filter);
Device* p_device = (Device*)p_ks_device->Context;
//Get the ITunerProperties object from the filter
ITunerProperties* p_properties = p_device->getTunerProperties();
if(!p_properties)
{
return STATUS_UNSUCCESSFUL;
}
p_data->InputIndex = p_properties->_input;
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
//ITunerProperties::static_setInput
//
// Static DDK entry point for KSPROPERTY_TUNER_INPUT (set handler)
//
// Sets the input. Stored in the base class. Currently the value is ignored.
//
NTSTATUS ITunerProperties::static_setInput(
PIRP p_irp,
PKSPROPERTY_TUNER_INPUT_S p_request,
PKSPROPERTY_TUNER_INPUT_S p_data)
{
//Get the filter
PKSFILTER p_filter = KsGetFilterFromIrp(p_irp);
if(!p_filter)
{
return STATUS_UNSUCCESSFUL;
}
PKSDEVICE p_ks_device = KsFilterGetDevice(p_filter);
Device* p_device = (Device*)p_ks_device->Context;
//Get the ITunerProperties object from the filter
ITunerProperties* p_properties = p_device->getTunerProperties();
if(!p_properties)
{
return STATUS_UNSUCCESSFUL;
}
p_properties->_input = p_request->InputIndex;
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
//ITunerProperties::static_getStatus
//
// static DDK entry point for KSPROPERTY_TUNER_STATUS
//
// Calls the child class to get the tuner status
//
NTSTATUS ITunerProperties::static_getStatus(
PIRP p_irp,
PKSPROPERTY_TUNER_STATUS_S p_request,
PKSPROPERTY_TUNER_STATUS_S p_data)
{
LONG offset;
//Get the filter
PKSFILTER p_filter = KsGetFilterFromIrp(p_irp);
if(!p_filter)
{
return STATUS_UNSUCCESSFUL;
}
PKSDEVICE p_ks_device = KsFilterGetDevice(p_filter);
Device* p_device = (Device*)p_ks_device->Context;
//Get the ITunerProperties object from the filter
ITunerProperties* p_properties = p_device->getTunerProperties();
if(!p_properties)
{
return STATUS_UNSUCCESSFUL;
}
//TODO
/*
// set activity state
p_device->setCfpmActivityState(analogTuner_pwr_block,true);
// verify whether the device is powered up or not
p_device->setCfpmPowerMode(analogTuner_pwr_block, WAKEUP);
if ((!p_properties->_p_device->IsBoardCombo()) &&
(p_properties->_p_device->getCurrentGraphMode() == GRAPH_MODE_DIGITAL)
)
{
// set activity state
p_device->setCfpmActivityState(analogTuner_pwr_block,false);
DbgLogWarn(("ITunerProperties::static_getStatus : Tuner already acquired by BDA !!!\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
*/
// Get the offset
offset = p_properties->getSignalOffset();
p_data->SignalStrength = (offset == 0) ? 100 : 0;
p_data->PLLOffset = (offset == -1) ? 2 : -(offset/GRANULARITY_TV);
p_data->CurrentFrequency = p_properties->_frequency;
p_data->Busy = FALSE;
// set activity state
//TODO p_device->setCfpmActivityState(analogTuner_pwr_block,false);
return STATUS_SUCCESS;
}
NTSTATUS ITunerProperties::registerFilter(PDEVICE_OBJECT pdo, DWORD medium_id)
{
g_tuner_mediums[0].Id = medium_id; //video output
g_tuner_mediums[1].Id = medium_id; //audio output
return KsRegisterFilterWithNoKSPins(
pdo,
&KSCATEGORY_TVTUNER,
NUM_TUNER_PINS,
g_tuner_pin_direction,
g_tuner_mediums,
NULL);
}
ITuner* ITunerProperties::getTuner(DWORD mode /*=0*/)
{
//TODO: Visit the logic to enable for tuner2
if(mode == 0)
{
mode = _mode;
}
_p_device->acquireTunerMutex();
if(_p_tuner1 && (_p_tuner1->getSupportedModes() & mode))
{
_p_device->releaseTunerMutex();
return _p_tuner1;
}
if(_p_tuner2 && (_p_tuner2->getSupportedModes() & mode))
{
_p_device->releaseTunerMutex();
return _p_tuner2;
}
_p_device->releaseTunerMutex();
return NULL;
}
NTSTATUS ITunerProperties::setFrequency(ULONG frequency, ULONG country, DWORD tuning_flags)
{
DbgLogInfo(("ITunerProperties::setFrequency %ld\n",frequency));
if((country != _country_code) && (country != 0xFFFFFFFF))
{
setCountry(country);
}
IVideoDecoder* p_vid_dec = _p_device->getVidDec();
DWORD standard = p_vid_dec->getVideoStandard();
//Get the video and audio standards for the country.
KS_AnalogVideoStandard video_standard;
AUDIO_STANDARD audio_standard;
if(!getVideoAndAudioStandardsForCountry(country, &video_standard, &audio_standard))
{
return STATUS_UNSUCCESSFUL;
}
else if (video_standard != standard)
{
DbgLogWarn(("ITunerProperties::setFrequency : Video Standard mismatch - resetting to proper standard !!!\n"));
setCountry(country);
}
if (_p_device->getTunerMode() == TUNER_MODE_ANALOG)
{
if(
(frequency == 0xFFFFFFFF) || // or it is a bad freq
((frequency == _frequency) && (getSignalOffset() == 0)) // If it is the same freq and we have a lock
)
{
return STATUS_SUCCESS;
}
}
ITuner* p_tuner = getTuner();
if(!p_tuner)
{
return STATUS_UNSUCCESSFUL;
}
_received_change_frequency = TRUE;
//Send the pre-channel change notification if we are using the driver tunes
// strategy, or if we are using the PLL tuning strategy and we do not have
// and active channel change thread. (Meaning that this is one in a number of calls
// user mode will make to do a single tuning operation, and we do not want to
// send the post channel change before it is done with all the calls)
if(!_use_pll_tune || !_channel_change_thread_object)
{
_p_device->notifyPreChannelChange();
}
NTSTATUS status = STATUS_SUCCESS;
_p_device->acquireTunerMutex();
//If we are using the PLL tune, call the version without the tuning flags. This
// version will tune and return immediately. The other version will retry
// according to the value in the tuning flags.
if(_use_pll_tune)
{
p_tuner->setFrequency(frequency, standard);
}
else
{
DirectIF *pDIF = _p_device->getDirectIF();
if (pDIF)
pDIF->preChannelChange();
p_tuner->setFrequency(&frequency, standard, tuning_flags);
if(pDIF)
pDIF->postChannelChange();
}
_p_device->releaseTunerMutex();
if(status == STATUS_SUCCESS)
{
//Save the new frequency
_frequency = frequency;
_tuning_flags = tuning_flags;
}
//Send the post channel change notification if we are using the driver tunes strategy.
// If we are using PLL tunes, the channel change thread will send the notification
// for us.
if( (!_use_pll_tune) && (p_vid_dec))
{
p_vid_dec->EnableACGEnAndCKillen(TRUE, TRUE);
// _p_device->notifyPostChannelChange();
}
// else if(!_channel_change_thread_object)
if( (!_channel_change_thread_object) && (_p_device->DeviceActive()))
{
startChannelChangeThread();
}
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
//static_channelChangeThread
//
// This thread is used to figure out when the beginning and end of a channel change
// occurs. A single channel change can cause many calls to TunerSetFrequency, especially
// in antenna mode, when the tuner will go back and forth trying to lock on a valid
// frequency. This can be up to 20 calls.
//
// There are events in VCAP that should occur while a channel change is happening, but
// we need to be able to know when the change is done so that we do not do things like
// reallocate the audio standard many times.
//
VOID ITunerProperties::static_channelChangeThread(ITunerProperties* p_tuner_properties)
{
//Wait until no new SetChannelFrequency command is received for 200 ms
while(p_tuner_properties->_received_change_frequency && p_tuner_properties->_p_device->DeviceActive())
{
p_tuner_properties->_received_change_frequency = FALSE;
sleep(300);
}
if (p_tuner_properties->_p_device->DeviceActive())
{
p_tuner_properties->_p_device->notifyPostChannelChange();
}
//Set our thread object to NULL so that a new thread is started next time.
p_tuner_properties->_channel_change_thread_object = NULL;
p_tuner_properties->SetChangeChannelThreadState(FALSE);
}
/////////////////////////////////////////////////////////////////////////////////////////
//startChannelChangeThread
//
// Starts the channel change thread above.
//
//
NTSTATUS ITunerProperties::startChannelChangeThread()
{
HANDLE ThreadHandle;
NTSTATUS Status = PsCreateSystemThread(
&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
NULL,
(PKSTART_ROUTINE) ITunerProperties::static_channelChangeThread, //Thread routine
this); //Context
if(!NT_SUCCESS(Status))
return Status;
return ObReferenceObjectByHandle(
ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&_channel_change_thread_object,
NULL);
}
LONG ITunerProperties::getSignalOffset()
{
LONG offset = 0;
ITuner* p_tuner = getTuner();
if(!p_tuner)
{
return STATUS_UNSUCCESSFUL;
}
Merlin* paudDec = _p_device->getAudDec();
//
if ((KSPROPERTY_TUNER_MODE_FM_RADIO == _mode) && paudDec)
{
// enable Hammerhead block
//TODO _p_device->setCfpmPowerMode(hammerhead_pwr_block, WAKEUP);
// enable Flat Iron block
//TODO _p_device->setCfpmPowerMode(flatIron_pwr_block, WAKEUP);
// Most of the boards we have FM on the SIF, so we can query Merlin for lock.
if (paudDec->isFMLocked())
{
offset = 0;
}
else
{
offset = 100;
}
}
else
{
_p_device->acquireTunerMutex();
offset = p_tuner->getSignalOffset();
_p_device->releaseTunerMutex();
}
return(offset);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -