btcard.cpp
来自「一个开放源码的bt848/878驱动程序的源码」· C++ 代码 · 共 1,724 行 · 第 1/5 页
CPP
1,724 行
m_ksCurrentTunerStandard = ksStandard;
// And that we changed things successfully.
st = STATUS_SUCCESS;
} else {
DUMP(("TunerChip[%d] does NOT support standard %08X, supported are %08X\n",Idx,ksStandard,TunerChip[Idx]->TVTunerVideoStandardsSupported()));
}
} else {
DUMP(("TunerChip[%d] can NOT tune TV!\n", Idx));
}
}
// If we were able to change...
if ( st == STATUS_SUCCESS ) {
// Inform of the video norm change...
for (Idx = 0 ; Idx < AudioCount ; Idx ++) {
AudioChip[Idx]->VideoStandardChanged(ksStandard);
}
// Now, Inform the audioChips that Channel has Changed ...
for (Idx = 0 ; Idx < AudioCount ; Idx ++) {
AudioChip[Idx]->ChannelChanged();
}
}
} else {
st = STATUS_SUCCESS;
}
DUMP(("Returning status %d, current standard %d, requested standard %d\n", st, m_ksCurrentTunerStandard, ksStandard));
return st;
}
NTSTATUS BtCard::TunerSetMode( ULONG Mode )
{
HwTuner::TunerMode tm = HwTuner::Tm_TV;
// Translate from WDM to our internal form
switch (Mode) {
case 0: // This is the DEFAULT mode based on DirectShow Docs (feature not documented on ntddk)
case KSPROPERTY_TUNER_MODE_TV:
tm = HwTuner::Tm_TV;
break;
case KSPROPERTY_TUNER_MODE_AM_RADIO:
tm = HwTuner::Tm_Radio_AM;
break;
case KSPROPERTY_TUNER_MODE_FM_RADIO:
tm = HwTuner::Tm_Radio_FM;
break;
default:
return STATUS_INVALID_PARAMETER;
}
// Only do if really changing mode !
if (m_CurrentTunerMode != tm) {
// Remember new Tuner Mode
m_CurrentTunerMode = tm;
// Make things easier : Despite WDM does not differenciate between Radio and TV tuner, we do, so remember mode
if (tm == HwTuner::Tm_TV || m_bTVAudioUsedForFM) {
// TV Tuner mode
TunerConnector = AudioConTuner;
} else {
// Radio Tuner mode
TunerConnector = AudioConRadio;
}
// Switch to appropiate connector if Tuner is selected
if ((AudioMux == AudioConTuner ||
AudioMux == AudioConRadio) &&
!bAudioMuted ) {
// Set the correct connector for Tuner!
AudioMux = TunerConnector;
// Get card information
CInfo* Info = GetCardInfo();
// Enable the corresponding GPIO pins to select audio sources...
GetBtPisces().SetGPOE( GetBtPisces().GetGPOE() | Info->gpoe );
// Set the correct bits to enable the Line Source
ULONG Val;
GetBtPisces().GetGPDATA(&Val,1,0);
Val &= ~Info->gpoe; // Keep all bits not involved into audio switching: all the others set to 0
Val |= Info->gpoe & Info->audiomux[AudioMux]; // And select the audio source without disrupting the other bits...
GetBtPisces().SetGPDATA(&Val,1,0);
// Now, For all the AudioChips, set the input!
for (DWORD Idx = 0 ; Idx < AudioCount ; Idx ++) {
AudioChip[Idx]->SetAudioConnector(AudioMux);
}
}
// Now, Set the mode!
// Based on mode requested, select the adequate handler )a possible IF change makes this a must...)
switch (m_CurrentTunerMode) {
case HwTuner::Tm_TV:
{
// Find the right chip
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneTV()) {
// This one should work ...
ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,m_CurrentTunerFrequency,HwTuner::Tm_Fine);
if (RealFreq) {
m_CurrentTunerFrequency = RealFreq;
}
m_TunerSignalDetected = (RealFreq != 0);
}
}
}
break;
case HwTuner::Tm_Radio_AM:
{
// Find the right chip
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneAM()) {
// This one should work ...
ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,m_CurrentTunerFrequency,HwTuner::Tm_Fine);
if (RealFreq) {
m_CurrentTunerFrequency = RealFreq;
}
m_TunerSignalDetected = (RealFreq != 0);
}
}
}
break;
case HwTuner::Tm_Radio_FM:
{
// Find the right chip
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneFM()) {
// This one should work ...
ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,m_CurrentTunerFrequency,HwTuner::Tm_Fine);
if (RealFreq) {
m_CurrentTunerFrequency = RealFreq;
}
m_TunerSignalDetected = (RealFreq != 0);
}
}
}
break;
}
// Now, Inform the audioChips that Channel has Changed ...
for (DWORD Idx = 0 ; Idx < AudioCount ; Idx ++) {
AudioChip[Idx]->ChannelChanged();
}
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
ULONG BtCard::TunerGetMode()
{
// Translate from our internal form to WDM
switch (m_CurrentTunerMode) {
default:
case HwTuner::Tm_TV:
return KSPROPERTY_TUNER_MODE_TV;
case HwTuner::Tm_Radio_AM:
return KSPROPERTY_TUNER_MODE_AM_RADIO;
case HwTuner::Tm_Radio_FM:
return KSPROPERTY_TUNER_MODE_FM_RADIO;
}
return KSPROPERTY_TUNER_MODE_TV;
}
// Get capabilities for a given mode
NTSTATUS BtCard::TunerGetModeCaps( PKSPROPERTY_TUNER_MODE_CAPS_S pCaps)
{
switch (pCaps->Mode) {
case KSPROPERTY_TUNER_MODE_TV:
{
// Look for the first tuner that handles this ... And Get Caps!
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneTV()) {
// This one should work ...
TunerChip[Idx]->TVTunerCaps(
pCaps->MinFrequency,pCaps->MaxFrequency,
pCaps->TuningGranularity,pCaps->SettlingTime);
pCaps->StandardsSupported = TunerChip[Idx]->TVTunerVideoStandardsSupported();
return STATUS_SUCCESS;
}
}
break;
}
case KSPROPERTY_TUNER_MODE_AM_RADIO:
{
// Look for the first tuner that handles this ... And Get Caps!
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneAM()) {
// This one should work ...
TunerChip[Idx]->AMTunerCaps(
pCaps->MinFrequency,pCaps->MaxFrequency,
pCaps->TuningGranularity,pCaps->SettlingTime);
pCaps->StandardsSupported = 0;
return STATUS_SUCCESS;
}
}
break;
}
case KSPROPERTY_TUNER_MODE_FM_RADIO:
{
// Look for the first tuner that handles this ... And Get Caps!
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneFM()) {
// This one should work ...
TunerChip[Idx]->FMTunerCaps(
pCaps->MinFrequency,pCaps->MaxFrequency,
pCaps->TuningGranularity,pCaps->SettlingTime);
pCaps->StandardsSupported = 0;
return STATUS_SUCCESS;
}
}
break;
}
}
return STATUS_INVALID_PARAMETER;
}
NTSTATUS BtCard::TunerSetFrequency( DWORD Frequency ,KS_TUNER_TUNING_FLAGS tf) // Frequency of channel
{
TRACE(("BtCard::TunerSetFrequency"));
// Translate the Tuning Method
HwTuner::TuningMethod method = HwTuner::Tm_Fine;
DUMP((" Frequency requested %d, using tuning flags %d\n",
Frequency, tf ));
// This should be in this way, but the Default TV tuner dialog box does not
// pass KS_TUNER_TUNING_FINE, so we will have to add some workarounds...
if (tf == KS_TUNER_TUNING_COARSE) {
method = HwTuner::Tm_Coarse;
} else if (tf == KS_TUNER_TUNING_EXACT) {
method = HwTuner::Tm_Exact;
}
// Remember the current tuning method...
m_TunerCurrMethod = tf;
// Only set Frequency if frequency and/or tuning mode has really changed!
if (Frequency != m_CurrentTunerFrequency || method != m_TunerLastMethod) {
// Remember last tuning method
m_TunerLastMethod = method;
// Remember muted state and mute
BOOL PrevMuted = bAudioMuted;
AudioMute();
// Based on mode requested, select the adequate handler
switch (m_CurrentTunerMode) {
case HwTuner::Tm_TV:
{
// Find the right chip
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneTV()) {
// This one should work ...
ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,method);
// Delay to allow the video signal to stabilise
mdelay( 35 );
// If the requested method isn't fine tuning, but we locked on a signal
// then tune again with fine tuning but only when the new tuning
// has been selected
if (method != HwTuner::Tm_Fine && IsHLocked() ) {
DUMP(( "SetFrequency found signal lock, fine tuning\n" ));
RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,HwTuner::Tm_Fine );
}
if (RealFreq) {
m_CurrentTunerFrequency = RealFreq;
} else {
m_CurrentTunerFrequency = Frequency;
}
m_TunerSignalDetected = (RealFreq != 0);
}
}
}
break;
case HwTuner::Tm_Radio_AM:
{
// Find the right chip
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneAM()) {
// This one should work ...
ULONG RealFreq = TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,method);
if (RealFreq) {
m_CurrentTunerFrequency = RealFreq;
} else {
m_CurrentTunerFrequency = Frequency;
}
m_TunerSignalDetected = (RealFreq != 0);
}
}
}
break;
case HwTuner::Tm_Radio_FM:
{
// Find the right chip
for (DWORD Idx = 0 ; Idx < TunerCount ; Idx ++) {
if (TunerChip[Idx]->CanTuneFM()) {
// This one should work ...
ULONG RealFreq= TunerChip[Idx]->SetFrequency(m_ksCurrentTunerStandard,m_CurrentTunerMode,Frequency,method);
if (RealFreq) {
m_CurrentTunerFrequency = RealFreq;
} else {
m_CurrentTunerFrequency = Frequency;
}
m_TunerSignalDetected = (RealFreq != 0);
}
}
}
break;
}
// If previously unmuted, unmute now!
if (!PrevMuted) {
AudioUnmute();
}
// Now, Inform the audioChips that Channel has Changed ...
for (DWORD Idx = 0 ; Idx < AudioCount ; Idx ++) {
AudioChip[Idx]->ChannelChanged();
}
}
return STATUS_SUCCESS;
}
// Power management
NTSTATUS BtCard::PowerDown()
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?