Introduction
If you are developing a TV tuner application for your tuner device using Direct Show, then you will definitely look for some function which can perform fine TV tuning (i.e., you want to set video frequency manually to get the precise video signal on a specific TV channel), but unfortunately, there in no such function in standard DirectShow TV tuning interfaces IAMTuner
and IAMTVTuner
.
The DirectShow TV tuning architecture is based on pre-defined frequency tables, and the TV Tuner filter (kstvtune.ax) has an internal list of frequency tables. Each frequency table contains a list of frequencies, and corresponds to the broadcast or cable frequencies for a given country/region. So, when you use the IAMTuner
interface, it gets the channel frequency values from the internal frequency tables according to the selected country/ region and tunes the TV channels.
Because the IAMTuner
interface will not allow you to modify the frequency values for a specific channel manually, you can't fine tune a channel while previewing. However, there is an AutoTune
function available in IAMTVTuner
interface which can help you to fine tune a channel, but this will also give you no control for manual fine tuning on the fly or to set custom video frequencies.
But the following code will describe you the complete details of fine tuning on the fly using IKsPropertySet
. I am writing this article only to help those who really want to get some clue on fine TV tuning because I know how difficult it is to get help on this topic. Even, you will not find a single function in the whole DirectShow documentation which can help you on this.
While writing this code, I assumed that the reader has good knowledge of DirectShow video capturing and know the details of DirectShow graph building techniques, filers, and TV tuner graphs. I hope the DirectShow guys will be happy after reading this article.
This is my first article on Code Project, so some of you may find it difficult to read ;).
#define INSTANCEDATA_OF_PROPERTY_PTR(x) ((PKSPROPERTY((x))) + 1)
#define INSTANCEDATA_OF_PROPERTY_SIZE(x) (sizeof((x)) - sizeof(KSPROPERTY))
HRESULT SetFrequency(long Freq)
{
HRESULT hr;
DWORD dwSupported=0;
CComPtr m_pKSProp;
hr = m_pTvtuner->QueryInterface(IID_IKsPropertySet, (void**)&m_pKSProp);
if (FAILED(hr))
return E_FAIL;
KSPROPERTY_TUNER_MODE_CAPS_S ModeCaps;
KSPROPERTY_TUNER_FREQUENCY_S Frequency;
memset(&ModeCaps,0,sizeof(KSPROPERTY_TUNER_MODE_CAPS_S));
memset(&Frequency,0,sizeof(KSPROPERTY_TUNER_FREQUENCY_S));
ModeCaps.Mode = AMTUNER_MODE_TV;
hr = m_pKSProp->QuerySupported(PROPSETID_TUNER,
KSPROPERTY_TUNER_MODE_CAPS,&dwSupported);
if(SUCCEEDED(hr) && dwSupported&KSPROPERTY_SUPPORT_GET)
{
DWORD cbBytes=0;
hr = m_pKSProp->Get(PROPSETID_TUNER,KSPROPERTY_TUNER_MODE_CAPS,
INSTANCEDATA_OF_PROPERTY_PTR(&ModeCaps),
INSTANCEDATA_OF_PROPERTY_SIZE(ModeCaps),
&ModeCaps,
sizeof(ModeCaps),
&cbBytes);
}
else
return E_FAIL;
Frequency.Frequency=Freq;
if(ModeCaps.Strategy==KS_TUNER_STRATEGY_DRIVER_TUNES)
Frequency.TuningFlags=KS_TUNER_TUNING_FINE;
else
Frequency.TuningFlags=KS_TUNER_TUNING_EXACT;
if(Freq>=ModeCaps.MinFrequency && Freq<=ModeCaps.MaxFrequency)
{
hr = m_pKSProp->Set(PROPSETID_TUNER,
KSPROPERTY_TUNER_FREQUENCY,
INSTANCEDATA_OF_PROPERTY_PTR(&Frequency),
INSTANCEDATA_OF_PROPERTY_SIZE(Frequency),
&Frequency,
sizeof(Frequency));
if(FAILED(hr))
return E_FAIL;
}
else
return E_FAIL;
return S_OK;
}
Explanation of Code
The SetFrequency
functions set the video frequency of a tuner device, the only parameter Freq
is the desired video frequency in Hz. The code is using IKsPropertySet
interface to perform the desired operations, IKsPropertySet
interface is part of the WDM KS (Win32� Driver Model Kernel Streaming) architecture and allows drivers to provide extended capabilities that can be used without API extensions.
The basic 3 steps performed by this code are..
- Check the support of
IKsPropertySet
on Tuner Drivers.
- Check the
PROPSETID_TUNER
property on Tuner Drivers.
- Set the user defined video frequency on tuner in Hz.
Using the Code
The SetFrequency
function can be used in several ways, i.e., fine TV tuning, manual TV tuning, new TV channels tuning, and etc.
- Fine tuning of a tuned TV channel.
- Call
IAMTuner::put_Channel
to set the desired TV channel.
- Call
IAMTVTuner::get_VideoFrequency
to get the current video frequency.
- Call
SetFrequency
by adding the desired +/- frequency value in the original channel frequency and perform the operation until you find the best video quality on that channel.
- Manual TV tuning.