Commit 89006bba authored by kbeliak's avatar kbeliak Committed by Jean-Baptiste Kempf

BDA: support for DVB-T2

Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent 160b51a3
......@@ -37,6 +37,7 @@ class IDVBCLocator;
class IDVBSLocator;
class IDVBSTuningSpace;
class IDVBTLocator;
class IDVBTLocator2;
class IDVBTuneRequest;
class IDVBTuningSpace;
class IDVBTuningSpace2;
......@@ -517,6 +518,13 @@ public:
VARIANT_BOOL OtherFrequencyInUseVal )=0;
};
class IDVBTLocator2 : public IDVBTLocator
{
public:
virtual HRESULT __stdcall get_PhysicalLayerPipeId( long* pl_plp )=0;
virtual HRESULT __stdcall put_PhysicalLayerPipeId( long l_plp )=0;
};
class ITuningSpace : public IDispatch
{
public:
......@@ -990,6 +998,10 @@ extern const CLSID CLSID_DVBSNetworkProvider;
extern const CLSID CLSID_DVBSTuningSpace;
extern const CLSID CLSID_DVBTuningSpace;
extern const CLSID CLSID_DVBTLocator;
/* Following symbol does not exist in library
extern const CLSID CLSID_DVBTLocator2; */
const CLSID CLSID_DVBTLocator2 =
{0xEFE3FA02,0x45D7,0x4920,{0xBE,0x96,0x53,0xFA,0x7F,0x35,0xB0,0xE6}};
extern const CLSID CLSID_DVBTNetworkProvider;
extern const CLSID CLSID_FilterGraph;
extern const CLSID CLSID_InfTee;
......@@ -1011,6 +1023,10 @@ const IID IID_IBDA_Topology =
{0x79B56888,0x7FEA,0x4690,{0xB4,0x5D,0x38,0xFD,0x3C,0x78,0x49,0xBE}};
extern const IID IID_ICreateDevEnum;
extern const IID IID_IDVBTLocator;
/* Following symbol does not exist in library
extern const IID IID_IDVBTLocator2; */
const IID IID_IDVBTLocator2 =
{0x448A2EDF,0xAE95,0x4b43,{0xA3,0xCC,0x74,0x78,0x43,0xC4,0x53,0xD4}};
extern const IID IID_IDVBCLocator;
extern const IID IID_IDVBSLocator;
extern const IID IID_IDVBSTuningSpace;
......
......@@ -235,11 +235,13 @@ int dvb_set_dvbt (dvb_device_t *d, uint32_t freq, const char * /*mod*/,
bandwidth, transmission, guard, hierarchy);
}
int dvb_set_dvbt2 (dvb_device_t *, uint32_t /*freq*/, const char * /*mod*/,
uint32_t /*fec*/, uint32_t /*bandwidth*/, int /*tx_mode*/,
uint32_t /*guard*/, uint32_t /*plp*/)
/* DVB-T2 */
int dvb_set_dvbt2 (dvb_device_t *d, uint32_t freq, const char * /*mod*/,
uint32_t fec, uint32_t bandwidth, int transmission,
uint32_t guard, uint32_t plp)
{
return VLC_EGENERIC;
return d->module->SetDVBT2(freq / 1000, fec,
bandwidth, transmission, guard, plp);
}
/* ISDB-C */
......@@ -910,6 +912,211 @@ int BDAGraph::SetDVBT(long l_frequency, uint32_t fec_hp, uint32_t fec_lp,
return VLC_SUCCESS;
}
/*****************************************************************************
* Set DVB-T2
*
* This provides the tune request that everything else is built upon.
*
* Stores the tune request to the scanning tuner, where it is pulled out by
* dvb_tune a/k/a SubmitTuneRequest.
******************************************************************************/
int BDAGraph::SetDVBT2(long l_frequency, uint32_t fec,
long l_bandwidth, int transmission, uint32_t guard, int plp)
{
HRESULT hr = S_OK;
class localComPtr
{
public:
ITuneRequest* p_tune_request;
IDVBTuneRequest* p_dvb_tune_request;
IDVBTLocator2* p_dvbt_locator;
IDVBTuningSpace2* p_dvb_tuning_space;
localComPtr():
p_tune_request(NULL),
p_dvb_tune_request(NULL),
p_dvbt_locator(NULL),
p_dvb_tuning_space(NULL)
{};
~localComPtr()
{
if( p_tune_request )
p_tune_request->Release();
if( p_dvb_tune_request )
p_dvb_tune_request->Release();
if( p_dvbt_locator )
p_dvbt_locator->Release();
if( p_dvb_tuning_space )
p_dvb_tuning_space->Release();
}
} l;
/* create local dvbt-specific tune request and locator
* then put it to existing scanning tuner */
BinaryConvolutionCodeRate i_fec = dvb_parse_fec(fec);
GuardInterval i_guard = dvb_parse_guard(guard);
TransmissionMode i_transmission = dvb_parse_transmission(transmission);
long l_plp = plp;
/* try to set p_scanning_tuner */
msg_Dbg( p_access, "SetDVBT: set up scanning tuner" );
hr = Check( CLSID_DVBTNetworkProvider );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot create Tuning Space: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
if( !p_scanning_tuner )
{
msg_Warn( p_access, "SetDVBT: Cannot get scanning tuner" );
return VLC_EGENERIC;
}
hr = p_scanning_tuner->get_TuneRequest( &l.p_tune_request );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot get Tune Request: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
msg_Dbg( p_access, "SetDVBT: Creating DVB tune request" );
hr = l.p_tune_request->QueryInterface( IID_IDVBTuneRequest,
reinterpret_cast<void**>( &l.p_dvb_tune_request ) );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot QI for IDVBTuneRequest: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
l.p_dvb_tune_request->put_ONID( -1 );
l.p_dvb_tune_request->put_SID( -1 );
l.p_dvb_tune_request->put_TSID( -1 );
msg_Dbg( p_access, "SetDVBT: get TS" );
hr = p_scanning_tuner->get_TuningSpace( &p_tuning_space );
if( FAILED( hr ) )
{
msg_Dbg( p_access, "SetDVBT: "\
"cannot get tuning space: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
msg_Dbg( p_access, "SetDVBT: QI to DVBT TS" );
hr = p_tuning_space->QueryInterface( IID_IDVBTuningSpace2,
reinterpret_cast<void**>( &l.p_dvb_tuning_space ) );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot QI for IDVBTuningSpace2: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
msg_Dbg( p_access, "SetDVBT: Creating local locator2" );
hr = ::CoCreateInstance( CLSID_DVBTLocator2, 0, CLSCTX_INPROC,
IID_IDVBTLocator2, reinterpret_cast<void**>( &l.p_dvbt_locator ) );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot create the DVBT Locator2: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
hr = l.p_dvb_tuning_space->put_SystemType( DVB_Terrestrial );
if( SUCCEEDED( hr ) && l_frequency > 0 )
hr = l.p_dvbt_locator->put_CarrierFrequency( l_frequency );
if( SUCCEEDED( hr ) && l_bandwidth > 0 )
hr = l.p_dvbt_locator->put_Bandwidth( l_bandwidth );
if( SUCCEEDED( hr ) && i_fec != BDA_BCC_RATE_NOT_SET )
hr = l.p_dvbt_locator->put_InnerFECRate( i_fec );
if( SUCCEEDED( hr ) && i_fec != BDA_BCC_RATE_NOT_SET )
hr = l.p_dvbt_locator->put_LPInnerFECRate( i_fec );
if( SUCCEEDED( hr ) && i_guard != BDA_GUARD_NOT_SET )
hr = l.p_dvbt_locator->put_Guard( i_guard );
if( SUCCEEDED( hr ) && i_transmission != BDA_XMIT_MODE_NOT_SET )
hr = l.p_dvbt_locator->put_Mode( i_transmission );
if( SUCCEEDED( hr ) && l_plp > 0 ){
hr = l.p_dvbt_locator->put_PhysicalLayerPipeId( l_plp);
}
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot set tuning parameters on Locator: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
msg_Dbg( p_access, "SetDVBT: putting DVBT locator into local tune request" );
hr = l.p_dvb_tune_request->put_Locator( l.p_dvbt_locator );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot put the locator: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
msg_Dbg( p_access, "SetDVBT: putting local Tune Request to scanning tuner" );
hr = p_scanning_tuner->Validate( l.p_dvb_tune_request );
if( FAILED( hr ) )
{
msg_Dbg( p_access, "SetDVBT: "\
"Tune Request cannot be validated: hr=0x%8lx", hr );
}
/* increments ref count for scanning tuner */
hr = p_scanning_tuner->put_TuneRequest( l.p_dvb_tune_request );
if( FAILED( hr ) )
{
msg_Warn( p_access, "SetDVBT: "\
"Cannot put the tune request: hr=0x%8lx", hr );
return VLC_EGENERIC;
}
/* TBS tuner PLP set workaround */
/* TODO: Check TBS tuner is present */
IPin* pinInput0 = FindPinOnFilter( p_tuner_device, "Input0");
if( pinInput0)
{
msg_Dbg( p_access, "SetDVBT: pin Input0 found on tuner filter, trying to get IKsPropertySet interface for TBS tuner..." );
IKsPropertySet* p_ksPropertySet;
hr = pinInput0->QueryInterface(IID_IKsPropertySet, reinterpret_cast<void**>(&p_ksPropertySet));
if( FAILED( hr ))
{
msg_Dbg( p_access, "SetDVBT: Cannot query for IKsPropertySet (this can be normal if not TBS tuner) : hr=0x%8lx", hr );
}
else
{
msg_Dbg( p_access, "SetDVBT: found IKsPropertySet interface (using TBS tuner PLP-set workaround)");
TBS_PLP_INFO plp_info;
ZeroMemory( &plp_info, sizeof( TBS_PLP_INFO));
plp_info.plpId = plp;
p_ksPropertySet->Set( KSPROPSETID_BdaTunerExtensionProperties,
KSPROPERTY_BDA_PLPINFO,
NULL,
0,
&plp_info,
sizeof( TBS_PLP_INFO ));
msg_Dbg( p_access, "SetDVBT: TBS tuner set PLP: %d", plp);
p_ksPropertySet->Release();
}
pinInput0->Release();
}
else
{
msg_Dbg( p_access, "SetDVBT: no pin Input0 found on tuner filter (this can be normal if not TBS tuner)" );
}
msg_Dbg( p_access, "SetDVBT: return success" );
return VLC_SUCCESS;
}
/*****************************************************************************
* Set DVB-C
******************************************************************************/
......@@ -1351,7 +1558,7 @@ int BDAGraph::SetDVBS(long l_frequency, long l_symbolrate, uint32_t fec,
* to the Network Type requested.
*
* Logic: if tuner is set up and is the right network type, use it.
* Otherwise, poll the tuner for the right tuning space.
* Otherwise, poll the tuner for the right tuning space.
*
* Then set up a tune request and try to validate it. Finally, put
* tune request and tuning space to tuner
......@@ -3115,3 +3322,67 @@ HRESULT BDAGraph::GetPinName( IPin* p_pin, char** psz_bstr_name )
pin_info.pFilter->Release();
return S_OK;
}
IPin* BDAGraph::FindPinOnFilter( IBaseFilter* pBaseFilter, const char* pPinName)
{
HRESULT hr;
IEnumPins *pEnumPin = NULL;
ULONG CountReceived = 0;
IPin *pPin = NULL, *pThePin = NULL;
char String[80];
char* pString;
PIN_INFO PinInfo;
int length;
if (!pBaseFilter || !pPinName)
return NULL;
// enumerate of pins on the filter
hr = pBaseFilter->EnumPins(&pEnumPin);
if (hr == S_OK && pEnumPin)
{
pEnumPin->Reset();
while (pEnumPin->Next( 1, &pPin, &CountReceived) == S_OK && pPin)
{
memset(String, 0, sizeof(String));
hr = pPin->QueryPinInfo(&PinInfo);
if (hr == S_OK)
{
length = wcslen (PinInfo.achName) + 1;
pString = new char [length];
// get the pin name
WideCharToMultiByte(CP_ACP, 0, PinInfo.achName, -1, pString, length,
NULL, NULL);
//strcat (String, pString);
//StringCbCat(String,strlen(String) + strlen(pString)+1,pString);
snprintf( String, strlen(String) + strlen(pString) + 1, "%s%s", String, pString);
// is there a match
if (strstr(String, pPinName))
pThePin = pPin; // yes
else
pPin = NULL; // no
delete pString;
}
else
{
// need to release this pin
pPin->Release();
}
} // end if have pin
// need to release the enumerator
pEnumPin->Release();
}
// return address of pin if found on the filter
return pThePin;
}
......@@ -39,6 +39,32 @@ using namespace std;
#include <comcat.h>
#include "dtv/bdadefs.h"
// TBS tuner extension headers
typedef struct _tbs_plp_info // PLP info for TBS tuners struct
{
unsigned char plpId; //The Rel PLPID need to set
unsigned char plpCount; //PLP count number
unsigned char plpResered1;//
unsigned char plpResered2;// memory size set to 4
unsigned char plpIdList[256];//store the Rel PLPID
} TBS_PLP_INFO,*p_TBS_PLP_INFO;
const GUID KSPROPSETID_BdaTunerExtensionProperties = {0xfaa8f3e5, 0x31d4, 0x4e41, {0x88, 0xef, 0xd9, 0xeb, 0x71, 0x6f, 0x6e, 0xc9}};
DWORD KSPROPERTY_BDA_PLPINFO = 22;
// End of TBS tuner extension headers
class BDAOutput
{
public:
......@@ -74,6 +100,7 @@ public:
int SetCQAM(long);
int SetATSC(long);
int SetDVBT(long, uint32_t, uint32_t, long, int, uint32_t, int);
int SetDVBT2(long, uint32_t, long, int, uint32_t, int);
int SetDVBC(long, const char *, long);
int SetDVBS(long, long, uint32_t, int, char, long, long, long);
......@@ -129,6 +156,7 @@ private:
HRESULT Check( REFCLSID guid_this_network_type );
HRESULT GetFilterName( IBaseFilter* p_filter, char** psz_bstr_name );
HRESULT GetPinName( IPin* p_pin, char** psz_bstr_name );
IPin* FindPinOnFilter( IBaseFilter* pBaseFilter, const char* pPinName);
unsigned GetSystem( REFCLSID clsid );
HRESULT ListFilters( REFCLSID this_clsid );
HRESULT FindFilter( REFCLSID clsid, long* i_moniker_used,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment