📄 props-txt.txt
字号:
#if 0
/* GUID struct: sizeof(GUID) = 16 */
typedef struct {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
/* KSPROPERTY struct: sizeof(KSPROPERTY) = 24 */
typedef struct {
union {
struct {
GUID Set;
ULONG Id;
ULONG Flags;
} Data;
LONGLONG Alignment;
};
} KSIDENTIFIER, *PKSIDENTIFIER, KSPROPERTY, *PKSPROPERTY;
/* KSPROPERTY_TUNER_FREQUENCY_S: sizeof(KSPROPERTY_TUNER_FREQUENCY_S) = 52 */
typedef struct {
KSPROPERTY Property;
ULONG Frequency; // Hz
ULONG LastFrequency; // Hz (last known good)
ULONG TuningFlags; // KS_TUNER_TUNING_FLAGS
ULONG VideoSubChannel; // DSS
ULONG AudioSubChannel; // DSS
ULONG Channel; // VBI decoders
ULONG Country; // VBI decoders
} KSPROPERTY_TUNER_FREQUENCY_S, *PKSPROPERTY_TUNER_FREQUENCY_S;
#endif
/*
Norm: Audio Carrier Video Bandwidth
SECAM_DKK1L 6.5MHz 6.0Mhz
PAL_D 6.5MHz 6.0MHz
PAL_I 6.0Mhz 5.5MHz
PAL_BGH 5.5Mhz 5.0MHz
PAL_N 5.5MHz 5.0MHz
SECAM_BG 5.5MHz 5.0MHz
NTSC_M 4.5Mhz 4.2MHz
PAL_M 4.5Mhz 4.2MHz
PAL_NC 4.5Mhz 4.2MHz
*/
// Ntsc50 is unsupported, we use NTSC433 to create it!
#ifndef AnalogVideo_NTSC_50
#define AnalogVideo_NTSC_50 AnalogVideo_NTSC_433
#endif
#define TN_CCIR_DKL \
AnalogVideo_PAL_D | \
AnalogVideo_SECAM_D | \
AnalogVideo_SECAM_K | \
AnalogVideo_SECAM_L
#define TN_CCIR_I \
AnalogVideo_PAL_I
#define TN_CCIR_BGHN \
AnalogVideo_PAL_B | \
AnalogVideo_PAL_G | \
AnalogVideo_PAL_H | \
AnalogVideo_PAL_N | \
AnalogVideo_PAL_60 | \
AnalogVideo_SECAM_B | \
AnalogVideo_SECAM_G
#define TN_CCIR_MC \
AnalogVideo_NTSC_M | \
AnalogVideo_NTSC_M_J | \
AnalogVideo_PAL_M | \
AnalogVideo_PAL_NC | \
AnalogVideo_NTSC_50
// Our access macros to get to the instance data of the property
#define INSTANCE_DATA_OF_PROPERTY_PTR(x) ( (PKSPROPERTY((x)) ) + 1 )
#define INSTANCE_DATA_OF_PROPERTY_SIZE(x) ( sizeof((x)) - sizeof(KSPROPERTY) )
// Fixed function: This is the correct implementation (the one that Microsoft is using)
// Method:
// SetFrequency
// Parameters:
// double ffreq = frequency to set in Megahertz
// AMTunerModeType lMode = Tuner mode to use (AMTUNER_MODE_TV, AMTUNER_MODE_FM_RADIO, AMTUNER_MODE_AM_RADIO )
// ULONG Input = RF input to use (0 should be ok for most tuners)
// AnalogVideoStandard TVstd = The analog video standard we are trying to use.
// Returns:
// TRUE if signal was found.
BOOL CTuner::SetFrequency(double ffreq,AMTunerModeType lMode , ULONG Input, AnalogVideoStandard TVstd)
{
DWORD Freq = ffreq * 1000000.;
DWORD ret = 0;
BOOL SignalFound = FALSE; // We start assuming signal is NOT present
// We should set Frequency, and we should do it using automatic fine tuning if
// possible... And we should check if a signal is present there... All this with the help
// of Microsoft Apis... Here we go!
IKsPropertySet *kps;
HRESULT hr = pTVTuner->QueryInterface(IID_IKsPropertySet,(void **)&kps);
if(FAILED(hr)) {
Log(__FUNC__,__LINE__,"QueryInterface",hr);
return FALSE;
}
// We query the capabilities of the tuner...
KSPROPERTY_TUNER_CAPS_S tc;
ZeroMemory(&tc,sizeof(tc));
ret = 0;
hr=kps->Get(PSET_TUNER,
KSPROPERTY_TUNER_CAPS,
INSTANCE_DATA_OF_PROPERTY_PTR(&tc), // The KSPROPERTY first member of the struct is ADDED by the IKsPropertySet::Set method, so we must pass a pointer to the fisrt element following the KSPROPERTY struct member (this is called "the instance data in the DirectX SDK")
INSTANCE_DATA_OF_PROPERTY_SIZE(tc), // This is the size of the instance data (you must consider the size of the struct MINUS the size of the KSPROPERTY, that is ADDED by the IKsPropertySet::Set method )
&tc, // Here we need a pointer to the property (NOT instance) data, so the pointer to the full propertyt struct is required.
sizeof(tc), // Here we need the size of the property (NOT instance) data, so the size of rhe full property struct is required.
&ret);
// If failed, log it (but all WDM drivers should support it, because it is a required property!)
if(FAILED(hr)) {
Log(__FUNC__,__LINE__,"KSPROPERTY_TUNER_CAPS",hr);
tc.ModesSupported = AMTUNER_MODE_TV; // at least, TV should be supported!
}
// Be sure the requested mode is supported!
if ((tc.ModesSupported & lMode) == 0) {
Log(__FUNC__,__LINE__,"Requested mode is not supported",hr);
// Release the interface, as we won't use it anymore.
kps->Release();
return FALSE;
}
// Get the capabilities of the tuner for the requested mode
KSPROPERTY_TUNER_MODE_CAPS_S tmc;
ZeroMemory(&tmc,sizeof(tmc));
ret = 0;
tmc.Mode = lMode; // We will query tuner caps for the mode we will set.
hr=kps->Get(PSET_TUNER,
KSPROPERTY_TUNER_MODE_CAPS,
INSTANCE_DATA_OF_PROPERTY_PTR(&tmc), // The KSPROPERTY first member of the struct is ADDED by the IKsPropertySet::Set method, so we must pass a pointer to the fisrt element following the KSPROPERTY struct member (this is called "the instance data in the DirectX SDK")
INSTANCE_DATA_OF_PROPERTY_SIZE(tmc), // This is the size of the instance data (you must consider the size of the struct MINUS the size of the KSPROPERTY, that is ADDED by the IKsPropertySet::Set method )
&tmc, // Here we need a pointer to the property (NOT instance) data, so the pointer to the full propertyt struct is required.
sizeof(tmc), // Here we need the size of the property (NOT instance) data, so the size of rhe full property struct is required.
&ret);
// If failed, log it (but all WDM drivers should support it, because it is a required property!)
if(FAILED(hr)) {
Log(__FUNC__,__LINE__,"KSPROPERTY_TUNER_MODE_CAPS",hr);
// Fake some values to be able to go on... (default capabilities should be close to this!)
switch (lMode) {
default:
case AMTUNER_MODE_TV;
// TV
// We will support all Video Standards (The KS_AnalogVideo... kernel enum is the AnalogVideo DirectX enum! , the MUST match, by Microsoft Specs)
tmc.StandardsSupported =
AnalogVideo_NTSC_M | AnalogVideo_NTSC_M_J | AnalogVideo_NTSC_433 |
AnalogVideo_PAL_B | AnalogVideo_PAL_D | AnalogVideo_PAL_H |
AnalogVideo_PAL_I | AnalogVideo_PAL_M | AnalogVideo_PAL_N |
AnalogVideo_PAL_60 | AnalogVideo_SECAM_B | AnalogVideo_SECAM_D |
AnalogVideo_SECAM_G | AnalogVideo_SECAM_H | AnalogVideo_SECAM_K |
AnalogVideo_SECAM_K1 | AnalogVideo_SECAM_L | AnalogVideo_SECAM_L1 |
AnalogVideo_PAL_N_COMBO;
// The lowest frequency supported by the tuner. This value is in hertz.
tmc.MinFrequency = 55250000L;
// The highest frequency supported by the tuner. This value is in hertz.
tmc.MaxFrequency = 997250000L;
// What is the frequency step size?
// The smallest possible step size between two settings of the tuning frequency. This value is in hertz.
tmc.TuningGranularity = 62500L;
// How many inputs are on the tuner? (some of them have more than 1 RF input)
// The number of inputs on the tuner.
tmc.NumberOfInputs = 1;
// What is the maximum settling time in milliseconds? (when you change frequency)
// The time, in milliseconds, for a new frequency setting to become stable.
tmc.SettlingTime = 100;
//
// Strategy defines how the tuner knows when it is in tune:
//
// KS_TUNER_STRATEGY_PLL (Has PLL offset information,else NO PLLOffset )
// KS_TUNER_STRATEGY_SIGNAL_STRENGTH (has signal strength info , else NO SignalStrength )
// KS_TUNER_STRATEGY_DRIVER_TUNES (driver handles all fine tuning) (No way to detect if signal is present)
//
tmc.Strategy = KS_TUNER_STRATEGY_DRIVER_TUNES;
break;
case AMTUNER_MODE_FM_RADIO:
tmc.StandardsSupported = 0;
tmc.MinFrequency = 88100000L;
tmc.MaxFrequency = 107900000L;
// What is the frequency step size?
tmc.TuningGranularity = 200000L;
// How many inputs are on the tuner?
tmc.NumberOfInputs = 1;
// What is the maximum settling time in milliseconds?
tmc.SettlingTime = 100;
// Strategy defines how the tuner knows when it is in tune:
tmc.Strategy = KS_TUNER_STRATEGY_DRIVER_TUNES;
break;
case KSPROPERTY_TUNER_MODE_AM_RADIO:
tmc.StandardsSupported = 0;
tmc.MinFrequency = 540000L;
tmc.MaxFrequency = 1700000L;
// What is the frequency step size?
tmc.TuningGranularity = 1000L;
// How many inputs are on the tuner?
tmc.NumberOfInputs = 1;
// What is the maximum settling time in milliseconds?
tmc.SettlingTime = 100;
// Strategy defines how the tuner knows when it is in tune:
tmc.Strategy = KS_TUNER_STRATEGY_DRIVER_TUNES;
break;
}
}
// Some buggy drivers don't properly report all the tuner analog video standards a tuner can tune:
// they only specify one of all the group: Fix that! - Some tuners need to be switched to the right
// video mode standard to be able to tune it.
if (tmc.StandardsSupported & TN_CCIR_DKL) { tmc.StandardsSupported |= TN_CCIR_DKL; }
if (tmc.StandardsSupported & TN_CCIR_I) { tmc.StandardsSupported |= TN_CCIR_I; }
if (tmc.StandardsSupported & TN_CCIR_BGHN) { tmc.StandardsSupported |= TN_CCIR_BGHN; }
if (tmc.StandardsSupported & TN_CCIR_MC) { tmc.StandardsSupported |= TN_CCIR_MC; }
// We have the capabilities for the current requested mode... Now validate parameters!
if (Freq < tmc.MinFrequency ||
Freq > tmc.MaxFrequency ||
(TVstd & tmc.StandardsSupported) == 0 ||
Input >= tmc.NumberOfInputs ) {
// Release the interface, as we won't use it anymore.
kps->Release();
// Frequency is out of tuner capabilities... Go out!
Log(__FUNC__,__LINE__,"Frequency and/or video standard is out of specification",hr);
// Out!
return FALSE;
}
// 1)- Set the tuner mode required (you could use IAMTuner::put_Mode()
// to do this; IAMTuner::put_Mode() uses this property to set the Tuner mode)
// (this property can also be read if needed)
KSPROPERTY_TUNER_MODE_S tm;
ZeroMemory(&tm,sizeof(tm));
tm.Mode = lMode; // The current tuner mode
hr=kps->Set(PSET_TUNER,
KSPROPERTY_TUNER_MODE,
INSTANCE_DATA_OF_PROPERTY_PTR(&tm), // The KSPROPERTY first member of the struct is ADDED by the IKsPropertySet::Set method, so we must pass a pointer to the fisrt element following the KSPROPERTY struct member (this is called "the instance data in the DirectX SDK")
INSTANCE_DATA_OF_PROPERTY_SIZE(tm), // This is the size of the instance data (you must consider the size of the struct MINUS the size of the KSPROPERTY, that is ADDED by the IKsPropertySet::Set method )
&tm, // Here we need a pointer to the property (NOT instance) data, so the pointer to the full propertyt struct is required.
sizeof(tm)); // Here we need the size of the property (NOT instance) data, so the size of rhe full property struct is required.
// 2)- Set the tuner Standard needed to tune to this
// (this property can also be read if needed)
KSPROPERTY_TUNER_STANDARD_S ts;
ZeroMemory(&ts,sizeof(ts));
ts.Standard = TVstd; // The current TV standard to set
hr=kps->Set(PSET_TUNER,
KSPROPERTY_TUNER_STANDARD,
INSTANCE_DATA_OF_PROPERTY_PTR(&ts), // The KSPROPERTY first member of the struct is ADDED by the IKsPropertySet::Set method, so we must pass a pointer to the fisrt element following the KSPROPERTY struct member (this is called "the instance data in the DirectX SDK")
INSTANCE_DATA_OF_PROPERTY_SIZE(ts), // This is the size of the instance data (you must consider the size of the struct MINUS the size of the KSPROPERTY, that is ADDED by the IKsPropertySet::Set method )
&ts, // Here we need a pointer to the property (NOT instance) data, so the pointer to the full propertyt struct is required.
sizeof(ts)); // Here we need the size of the property (NOT instance) data, so the size of rhe full property struct is required.
// Accept failure... Some drivers are buggy and probably tuning will work even if this fails
if(FAILED(hr))Log(__FUNC__,__LINE__,"KSPROPERTY_TUNER_STANDARD",hr);
// 3)- Set Tuner Input (this property can also be read if needed)
KSPROPERTY_TUNER_INPUT_S ti;
ZeroMemory(&ti,sizeof(ti));
ti.InputIndex = Input; // The input to use (0 based)
hr=kps->Set(PSET_TUNER,
KSPROPERTY_TUNER_INPUT,
INSTANCE_DATA_OF_PROPERTY_PTR(&ti), // The KSPROPERTY first member of the struct is ADDED by the IKsPropertySet::Set method, so we must pass a pointer to the fisrt element following the KSPROPERTY struct member (this is called "the instance data in the DirectX SDK")
INSTANCE_DATA_OF_PROPERTY_SIZE(ti), // This is the size of the instance data (you must consider the size of the struct MINUS the size of the KSPROPERTY, that is ADDED by the IKsPropertySet::Set method )
&ti, // Here we need a pointer to the property (NOT instance) data, so the pointer to the full propertyt struct is required.
sizeof(ti)); // Here we need the size of the property (NOT instance) data, so the size of rhe full property struct is required.
// Accept failure... Some drivers are buggy and probably tuning will work even if this fails
if(FAILED(hr))Log(__FUNC__,__LINE__,"KSPROPERTY_TUNER_INPUT",hr);
// We are ready to set frequency... Based on Tuner Strategy,
// try to fine tune to the requested channel and at the same time, try to find out if
// a signal is present there!
switch (tmc.Strategy) {
// Driver handles fine-tuning - Teoretically, no way to know if signal is present.
// I suggest to use IAMAnalogVideoDecoder::get_HorizontalLocked to know it if it is a video
// signal (Radio signals can't be autodetected this way!)
default:
case KS_TUNER_STRATEGY_DRIVER_TUNES:
{
// Set Frequency
KSPROPERTY_TUNER_FREQUENCY_S tf;
ZeroMemory(&tf,sizeof(tf));
tf.Frequency = Freq; // The frequency to set...
tf.TuningFlags = KS_TUNER_TUNING_FINE; // Let the driver do fine auto tuning.
hr=kps->Set(PSET_TUNER,
KSPROPERTY_TUNER_FREQUENCY,
INSTANCE_DATA_OF_PROPERTY_PTR(&tf), // The KSPROPERTY first member of the struct is ADDED by the IKsPropertySet::Set method, so we must pass a pointer to the fisrt element following the KSPROPERTY struct member (this is called "the instance data in the DirectX SDK")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -