⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 itunerproperties.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    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 + -