diff --git a/mythtv/libs/libmythtv/cardutil.cpp b/mythtv/libs/libmythtv/cardutil.cpp index 6c2cf39..32849c1 100644 --- a/mythtv/libs/libmythtv/cardutil.cpp +++ b/mythtv/libs/libmythtv/cardutil.cpp @@ -293,6 +293,11 @@ QString CardUtil::ProbeDVBType(const QString &device) close(fd_frontend); DTVTunerType type(info.type); +#if DVB_API_VERSION >= 5 + if (type == DTVTunerType::kTunerTypeQPSK && + (info.caps & FE_CAN_2G_MODULATION)) + type = DTVTunerType::kTunerTypeDVB_S2; +#endif // DVB_API_VERSION >= 5 ret = (type.toString() != "UNKNOWN") ? type.toString().toUpper() : ret; #endif // USING_DVB @@ -385,7 +390,7 @@ bool CardUtil::IsDVBCardType(const QString card_type) { QString ct = card_type.toUpper(); return (ct == "DVB") || (ct == "QAM") || (ct == "QPSK") || - (ct == "OFDM") || (ct == "ATSC"); + (ct == "OFDM") || (ct == "ATSC") || (ct == "DVB_S2"); } QString get_on_cardid(const QString &to_get, uint cardid) diff --git a/mythtv/libs/libmythtv/cardutil.h b/mythtv/libs/libmythtv/cardutil.h index 328b341..ea9e54c 100644 --- a/mythtv/libs/libmythtv/cardutil.h +++ b/mythtv/libs/libmythtv/cardutil.h @@ -55,6 +55,7 @@ class MPUBLIC CardUtil HDHOMERUN = 10, FREEBOX = 11, HDPVR = 12, + DVBS2 = 13, }; static enum CARD_TYPES toCardType(const QString &name) @@ -85,6 +86,8 @@ class MPUBLIC CardUtil return FREEBOX; if ("HDPVR" == name) return HDPVR; + if ("DVB_S2" == name) + return DVBS2; return ERROR_UNKNOWN; } diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp index 60a6661..a85034b 100644 --- a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp +++ b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp @@ -1547,7 +1547,8 @@ bool ChannelScanSM::ScanTransportsStartingOn( startChan["coderate_hp"], startChan["coderate_lp"], startChan["constellation"], startChan["trans_mode"], startChan["guard_interval"], startChan["hierarchy"], - startChan["modulation"], startChan["bandwidth"]); + startChan["modulation"], startChan["bandwidth"], + startChan["mod_sys"], startChan["rolloff"]); } if (ok) diff --git a/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h b/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h index 3c20d10..286d1fe 100644 --- a/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h +++ b/mythtv/libs/libmythtv/channelscan/channelscanmiscsettings.h @@ -228,6 +228,32 @@ class ScanHierarchy: public ComboBoxSetting, public TransientStorage }; }; +class ScanModSys: public ComboBoxSetting, public TransientStorage +{ + public: + ScanModSys() : ComboBoxSetting(this) + { + setLabel(QObject::tr("Mod Sys")); + setHelpText(QObject::tr("Modulation system (Default: DVB-S)")); + addSelection("DVB-S"); + addSelection("DVB-S2"); + }; +}; + +class ScanRollOff: public ComboBoxSetting, public TransientStorage +{ + public: + ScanRollOff() : ComboBoxSetting(this) + { + setLabel(QObject::tr("Rolloff")); + setHelpText(QObject::tr("Roll Off factor (Default: 0.35)")); + addSelection("0.35"); + addSelection("0.20"); + addSelection("0.25"); + addSelection(QObject::tr("Auto"),"auto"); + }; +}; + class PaneError : public HorizontalConfigurationGroup { public: diff --git a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp index b209eed..7bb16fe 100644 --- a/mythtv/libs/libmythtv/channelscan/channelscanner.cpp +++ b/mythtv/libs/libmythtv/channelscan/channelscanner.cpp @@ -157,9 +157,10 @@ void ChannelScanner::Scan( ok = sigmonScanner->ScanTransports( sourceid, freq_std, mod, tbl, tbl_start, tbl_end); } - else if ((ScanTypeSetting::NITAddScan_DVBT == scantype) || - (ScanTypeSetting::NITAddScan_DVBS == scantype) || - (ScanTypeSetting::NITAddScan_DVBC == scantype)) + else if ((ScanTypeSetting::NITAddScan_DVBT == scantype) || + (ScanTypeSetting::NITAddScan_DVBS == scantype) || + (ScanTypeSetting::NITAddScan_DVBS2 == scantype) || + (ScanTypeSetting::NITAddScan_DVBC == scantype)) { VERBOSE(VB_CHANSCAN, LOC + "ScanTransports()"); diff --git a/mythtv/libs/libmythtv/channelscan/modulationsetting.h b/mythtv/libs/libmythtv/channelscan/modulationsetting.h index 88f0254..67e25b2 100644 --- a/mythtv/libs/libmythtv/channelscan/modulationsetting.h +++ b/mythtv/libs/libmythtv/channelscan/modulationsetting.h @@ -58,9 +58,6 @@ class ScanModulationSetting: public ComboBoxSetting { addSelection(QObject::tr("Auto"),"auto",true); addSelection("QPSK","qpsk"); -#ifdef FE_GET_EXTENDED_INFO - addSelection("8PSK","8psk"); -#endif addSelection("QAM 16","qam_16"); addSelection("QAM 32","qam_32"); addSelection("QAM 64","qam_64"); @@ -90,5 +87,23 @@ class ScanConstellation: public ScanModulationSetting, }; }; +class ScanDVBSModulation: public ComboBoxSetting, public TransientStorage +{ + public: + ScanDVBSModulation() : ComboBoxSetting(this) + { + + addSelection("QPSK", "qpsk", true); + addSelection("8PSK", "8psk"); + addSelection("QAM 16","qam_16"); + + setLabel(QObject::tr("Modulation")); + setHelpText( + QObject::tr("Modulation, QPSK, 8PSK, QAM-16") + " " + + QObject::tr("Most DVB-S transponders use QPSK, DVB-S2 8PSK " + "QAM-16 is not available for DVB-S2 transports.")); + } +}; + #endif // _MODULATION_SETTING_H_ diff --git a/mythtv/libs/libmythtv/channelscan/panedvbs2.h b/mythtv/libs/libmythtv/channelscan/panedvbs2.h index 8a5742d..116b870 100644 --- a/mythtv/libs/libmythtv/channelscan/panedvbs2.h +++ b/mythtv/libs/libmythtv/channelscan/panedvbs2.h @@ -22,9 +22,11 @@ class PaneDVBS2 : public HorizontalConfigurationGroup left->addChild( pfrequency = new ScanFrequency()); left->addChild( ppolarity = new ScanPolarity()); left->addChild( psymbolrate = new ScanSymbolRate()); + left->addChild( pmod_sys = new ScanModSys()); right->addChild(pfec = new ScanFec()); - right->addChild(pmodulation = new ScanModulation()); + right->addChild(pmodulation = new ScanDVBSModulation()); right->addChild(pinversion = new ScanInversion()); + right->addChild(prolloff = new ScanRollOff()); addChild(left); addChild(right); } @@ -35,6 +37,8 @@ class PaneDVBS2 : public HorizontalConfigurationGroup QString fec(void) const { return pfec->getValue(); } QString polarity(void) const { return ppolarity->getValue(); } QString modulation(void) const { return pmodulation->getValue(); } + QString mod_sys(void) const { return pmod_sys->getValue(); } + QString rolloff(void) const { return prolloff->getValue(); } protected: ScanFrequency *pfrequency; @@ -42,7 +46,9 @@ class PaneDVBS2 : public HorizontalConfigurationGroup ScanInversion *pinversion; ScanFec *pfec; ScanPolarity *ppolarity; - ScanModulation *pmodulation; + ScanDVBSModulation *pmodulation; + ScanModSys *pmod_sys; + ScanRollOff *prolloff; }; #endif // _PANE_DVBS2_H_ diff --git a/mythtv/libs/libmythtv/channelscan/scaninfo.cpp b/mythtv/libs/libmythtv/channelscan/scaninfo.cpp index faeafd5..e01035e 100644 --- a/mythtv/libs/libmythtv/channelscan/scaninfo.cpp +++ b/mythtv/libs/libmythtv/channelscan/scaninfo.cpp @@ -81,7 +81,8 @@ ScanDTVTransportList LoadScan(uint scanid) " hp_code_rate, lp_code_rate, modulation, " " transmission_mode, guard_interval, hierarchy, " " modulation, bandwidth, sistandard, " - " tuner_type, transportid " + " tuner_type, transportid, mod_sys, " + " rolloff " "FROM channelscan_dtv_multiplex " "WHERE scanid = :SCANID"); query.bindValue(":SCANID", scanid); @@ -102,7 +103,8 @@ ScanDTVTransportList LoadScan(uint scanid) query.value(6).toString(), query.value(7).toString(), query.value(8).toString(), query.value(9).toString(), query.value(10).toString(), query.value(11).toString(), - query.value(12).toString()); + query.value(12).toString(), query.value(13).toString(), + query.value(14).toString()); query2.prepare( "SELECT " diff --git a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp index 2d36ed8..0eea8de 100644 --- a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp +++ b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.cpp @@ -140,6 +140,14 @@ void ScanTypeSetting::SetInput(const QString &cardids_inputname) addSelection(tr("Import existing scan"), QString::number(ExistingScanImport)); break; + case CardUtil::DVBS2: + addSelection(tr("Full Scan (Tuned)"), + QString::number(NITAddScan_DVBS2)); + addSelection(tr("Import channels.conf"), + QString::number(DVBUtilsImport)); + addSelection(tr("Import existing scan"), + QString::number(ExistingScanImport)); + break; case CardUtil::QAM: addSelection(tr("Full Scan (Tuned)"), QString::number(NITAddScan_DVBC)); @@ -225,6 +233,8 @@ ScanOptionalConfig::ScanOptionalConfig(ScanTypeSetting *_scan_type) : paneDVBC); addTarget(QString::number(ScanTypeSetting::NITAddScan_DVBS), paneDVBS); + addTarget(QString::number(ScanTypeSetting::NITAddScan_DVBS2), + paneDVBS2); addTarget(QString::number(ScanTypeSetting::NITAddScan_DVBT), paneDVBT); addTarget(QString::number(ScanTypeSetting::FullScan_ATSC), @@ -387,6 +397,20 @@ QMap ScanOptionalConfig::GetStartChan(void) const startChan["fec"] = pane->fec(); startChan["modulation"] = pane->modulation(); } + else if (ScanTypeSetting::NITAddScan_DVBS2 == st) + { + const PaneDVBS2 *pane = paneDVBS2; + + startChan["std"] = "dvb"; + startChan["frequency"] = pane->frequency(); + startChan["inversion"] = pane->inversion(); + startChan["symbolrate"] = pane->symbolrate(); + startChan["fec"] = pane->fec(); + startChan["modulation"] = pane->modulation(); + startChan["polarity"] = pane->polarity(); + startChan["mod_sys"] = pane->mod_sys(); + startChan["rolloff"] = pane->rolloff(); + } return startChan; } diff --git a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h index d69b1c5..4f4661d 100644 --- a/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h +++ b/mythtv/libs/libmythtv/channelscan/scanwizardconfig.h @@ -66,6 +66,7 @@ class ScanTypeSetting : public ComboBoxSetting, public TransientStorage // seen in the Network Information Tables to the scan. NITAddScan_DVBT, NITAddScan_DVBS, + NITAddScan_DVBS2, NITAddScan_DVBC, // Scan of all transports already in the database FullTransportScan, diff --git a/mythtv/libs/libmythtv/channelutil.cpp b/mythtv/libs/libmythtv/channelutil.cpp index df12092..b100a54 100644 --- a/mythtv/libs/libmythtv/channelutil.cpp +++ b/mythtv/libs/libmythtv/channelutil.cpp @@ -127,7 +127,8 @@ static uint insert_dtv_multiplex( signed char trans_mode, QString inner_FEC, QString constellation, signed char hierarchy, QString hp_code_rate, - QString lp_code_rate, QString guard_interval) + QString lp_code_rate, QString guard_interval, + QString mod_sys, QString rolloff) { MSqlQuery query(MSqlQuery::InitCon()); @@ -174,6 +175,10 @@ static uint insert_dtv_multiplex( "lp_code_rate = :LP_CODE_RATE, " : ""; updateStr += (!guard_interval.isNull()) ? "guard_interval = :GUARD_INTERVAL, " : ""; + updateStr += (!mod_sys.isNull()) ? + "mod_sys = :MOD_SYS, " : ""; + updateStr += (symbol_rate >= 0) ? + "rolloff = :ROLLOFF, " : ""; updateStr += (transport_id && !isDVB) ? "transportid = :TRANSPORTID, " : ""; @@ -205,6 +210,8 @@ static uint insert_dtv_multiplex( insertStr += (!hp_code_rate.isNull()) ? "hp_code_rate, " : ""; insertStr += (!lp_code_rate.isNull()) ? "lp_code_rate, " : ""; insertStr += (!guard_interval.isNull()) ? "guard_interval, " : ""; + insertStr += (!mod_sys.isNull()) ? "mod_sys, " : ""; + insertStr += (!rolloff.isNull()) ? "rolloff, " : ""; insertStr = insertStr.left(insertStr.length()-2) + ") "; insertStr += @@ -224,6 +231,8 @@ static uint insert_dtv_multiplex( insertStr += (!hp_code_rate.isNull()) ? ":HP_CODE_RATE, " : ""; insertStr += (!lp_code_rate.isNull()) ? ":LP_CODE_RATE, " : ""; insertStr += (!guard_interval.isNull()) ? ":GUARD_INTERVAL, " : ""; + insertStr += (!mod_sys.isNull()) ? ":MOD_SYS, " : ""; + insertStr += (!rolloff.isNull()) ? ":ROLLOFF, " : ""; insertStr = insertStr.left(insertStr.length()-2) + ");"; query.prepare((mplex) ? updateStr : insertStr); @@ -284,6 +293,10 @@ static uint insert_dtv_multiplex( query.bindValue(":LP_CODE_RATE", lp_code_rate); if (!guard_interval.isNull()) query.bindValue(":GUARD_INTERVAL",guard_interval); + if (!mod_sys.isNull()) + query.bindValue(":MOD_SYS", mod_sys); + if (!rolloff.isNull()) + query.bindValue(":ROLLOFF", rolloff); if (!query.exec() || !query.isActive()) { @@ -337,7 +350,8 @@ void handle_transport_desc(vector &muxes, const MPEGDescriptor &desc, cd.TransmissionModeString()[0].toAscii(), QString(), cd.ConstellationString(), cd.HierarchyString()[0].toAscii(), cd.CodeRateHPString(), - cd.CodeRateLPString(), cd.GuardIntervalString()); + cd.CodeRateLPString(), cd.GuardIntervalString(), + QString(), QString()); if (mux) muxes.push_back(mux); @@ -364,7 +378,8 @@ void handle_transport_desc(vector &muxes, const MPEGDescriptor &desc, -1, cd.FECInnerString(), QString(), -1, QString(), - QString(), QString()); + QString(), QString(), + cd.ModulationSystemString(), cd.RollOffString()); if (mux) muxes.push_back(mux); @@ -387,6 +402,7 @@ void handle_transport_desc(vector &muxes, const MPEGDescriptor &desc, -1, cd.FECInnerString(), QString::null, -1, QString::null, + QString::null, QString::null, QString::null, QString::null); if (mux) @@ -407,6 +423,7 @@ uint ChannelUtil::CreateMultiplex(int sourceid, QString sistandard, -1, QString::null, QString::null, -1, QString::null, + QString::null, QString::null, QString::null, QString::null); } @@ -420,7 +437,8 @@ uint ChannelUtil::CreateMultiplex( signed char trans_mode, QString inner_FEC, QString constellation, signed char hierarchy, QString hp_code_rate, - QString lp_code_rate, QString guard_interval) + QString lp_code_rate, QString guard_interval, + QString mod_sys, QString rolloff) { return insert_dtv_multiplex( sourceid, sistandard, @@ -432,7 +450,8 @@ uint ChannelUtil::CreateMultiplex( trans_mode, inner_FEC, constellation, hierarchy, hp_code_rate, - lp_code_rate, guard_interval); + lp_code_rate, guard_interval, + mod_sys, rolloff); } uint ChannelUtil::CreateMultiplex(uint sourceid, const DTVMultiplex &mux, @@ -448,7 +467,8 @@ uint ChannelUtil::CreateMultiplex(uint sourceid, const DTVMultiplex &mux, mux.trans_mode.toChar().toAscii(), mux.fec.toString(), mux.modulation.toString(), mux.hierarchy.toChar().toAscii(), mux.hp_code_rate.toString(), - mux.lp_code_rate.toString(), mux.guard_interval.toString()); + mux.lp_code_rate.toString(), mux.guard_interval.toString(), + mux.mod_sys.toString(), mux.rolloff.toString()); } diff --git a/mythtv/libs/libmythtv/channelutil.h b/mythtv/libs/libmythtv/channelutil.h index ed9fdb4..31de276 100644 --- a/mythtv/libs/libmythtv/channelutil.h +++ b/mythtv/libs/libmythtv/channelutil.h @@ -67,7 +67,8 @@ class MPUBLIC ChannelUtil signed char trans_mode, QString inner_FEC, QString constellation, signed char hierarchy, QString hp_code_rate, - QString lp_code_rate, QString guard_interval); + QString lp_code_rate, QString guard_interval, + QString mod_sys, QString rolloff); static uint CreateMultiplex(uint sourceid, const DTVMultiplex&, int transport_id, int network_id); diff --git a/mythtv/libs/libmythtv/dbcheck.cpp b/mythtv/libs/libmythtv/dbcheck.cpp index 15ef40e..89f35b2 100644 --- a/mythtv/libs/libmythtv/dbcheck.cpp +++ b/mythtv/libs/libmythtv/dbcheck.cpp @@ -18,7 +18,7 @@ using namespace std; #define MINIMUM_DBMS_VERSION 5,0,15 /// This is the DB schema version expected by the running MythTV instance. -const QString currentDatabaseVersion = "1238"; +const QString currentDatabaseVersion = "1239"; static bool UpdateDBVersionNumber(const QString &newnumber); static bool performActualUpdate( @@ -4661,6 +4661,22 @@ NULL return false; } + + if (dbver == "1238") + { + const char *updates[] = { +"ALTER TABLE dtv_multiplex CHANGE COLUMN modulation_system mod_sys VARCHAR(10) DEFAULT NULL;", +"ALTER TABLE dtv_multiplex CHANGE COLUMN roll_off rolloff VARCHAR(4) NULL DEFAULT NULL;", +"ALTER TABLE channelscan_dtv_multiplex ADD mod_sys VARCHAR(10) DEFAULT NULL" + " AFTER hp_code_rate;", +"ALTER TABLE channelscan_dtv_multiplex ADD rolloff VARCHAR(4) NULL DEFAULT NULL" + " AFTER mod_sys;", +NULL +}; + if (!performActualUpdate(updates, "1239", dbver)) + return false; + } + return true; } diff --git a/mythtv/libs/libmythtv/dtvconfparser.cpp b/mythtv/libs/libmythtv/dtvconfparser.cpp index 1dfedc1..bbaacc7 100644 --- a/mythtv/libs/libmythtv/dtvconfparser.cpp +++ b/mythtv/libs/libmythtv/dtvconfparser.cpp @@ -112,7 +112,7 @@ DTVConfParser::return_t DTVConfParser::Parse(void) { if ((type == OFDM) && (str == "T")) ok &= ParseVDR(list, channelNo); - else if ((type == QPSK) && (str == "S")) + else if ((type == QPSK || type == DVBS2) && (str == "S")) ok &= ParseVDR(list, channelNo); else if ((type == QAM) && (str == "C")) ok &= ParseVDR(list, channelNo); @@ -121,7 +121,7 @@ DTVConfParser::return_t DTVConfParser::Parse(void) ok &= ParseConfOFDM(list); else if (type == ATSC) ok &= ParseConfATSC(list); - else if (type == QPSK) + else if (type == QPSK || type == DVBS2) ok &= ParseConfQPSK(list); else if (type == QAM) ok &= ParseConfQAM(list); @@ -275,6 +275,12 @@ bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo) case 'L': mux.polarity.ParseVDR(ori); break; + case 'S': + mux.mod_sys.ParseVDR(params); + break; + case 'O': + mux.rolloff.ParseVDR(params); + break; default: return false; } diff --git a/mythtv/libs/libmythtv/dtvconfparser.h b/mythtv/libs/libmythtv/dtvconfparser.h index 2795493..a230782 100644 --- a/mythtv/libs/libmythtv/dtvconfparser.h +++ b/mythtv/libs/libmythtv/dtvconfparser.h @@ -80,7 +80,7 @@ class DTVConfParser { public: enum return_t { ERROR_CARDTYPE, ERROR_OPEN, ERROR_PARSE, OK }; - enum cardtype_t { ATSC, OFDM, QPSK, QAM, UNKNOWN }; + enum cardtype_t { ATSC, OFDM, QPSK, QAM, DVBS2, UNKNOWN }; DTVConfParser(enum cardtype_t _type, uint sourceid, const QString &_file); virtual ~DTVConfParser() { } diff --git a/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp b/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp index 697e882..7e255a1 100644 --- a/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp +++ b/mythtv/libs/libmythtv/dtvconfparserhelpers.cpp @@ -72,7 +72,7 @@ const DTVParamHelperStruct DTVTunerType::parseTable[] = { "DVB_S", kTunerTypeDVB_S }, { "DVB_C", kTunerTypeDVB_C }, { "DVB_T", kTunerTypeDVB_T }, - { "DVB_S2", kTunerTypeDVB_S2 }, + { "8PSK", kTunerTypeDVB_S2 }, { "UNKNOWN", kTunerTypeUnknown }, { NULL, kTunerTypeUnknown }, }; @@ -155,6 +155,8 @@ const DTVParamHelperStruct DTVCodeRate::confTable[] = { "FEC_7_8", kFEC_7_8 }, { "FEC_8_9", kFEC_8_9 }, { "FEC_NONE", kFECNone }, + { "FEC_3_5", kFEC_3_5 }, + { "FEC_9_10", kFEC_9_10 }, { NULL, kFECAuto }, }; @@ -170,6 +172,8 @@ const DTVParamHelperStruct DTVCodeRate::vdrTable[] = { "78", kFEC_7_8 }, { "89", kFEC_8_9 }, { "0", kFECNone }, + { "35", kFEC_3_5 }, + { "910", kFEC_9_10 }, { NULL, kFECAuto } }; @@ -199,7 +203,9 @@ const char *DTVCodeRate::dbStr[DTVCodeRate::kDBStrCnt] = "6/7", ///< kFEC_6_7 "7/8", ///< kFEC_7_8 "8/9", ///< kFEC_8_9 - "auto" ///< kFECAuto + "auto", ///< kFECAuto + "3/5", ///< KFEC_3_5 + "9/10", ///< KFEC_9_10 }; const DTVParamHelperStruct DTVModulation::confTable[] = @@ -213,26 +219,32 @@ const DTVParamHelperStruct DTVModulation::confTable[] = { "QPSK", kModulationQPSK }, { "8VSB", kModulation8VSB }, { "16VSB", kModulation16VSB }, - { "2VSB", kModulation2VSB }, - { "4VSB", kModulation4VSB }, - { "BPSK", kModulationBPSK }, + { "8PSK", kModulation8PSK }, { "16APSK", kModulation16APSK }, { "32APSK", kModulation32APSK }, - { "8PSK", kModulation8PSK }, - { "16PSK", kModulation16PSK }, + { "DQPSK", kModulationDQPSK }, + { "16PSK", kModulationInvalid }, + { "2VSB", kModulationInvalid }, + { "4VSB", kModulationInvalid }, + { "BPSK", kModulationInvalid }, { "analog", kModulationAnalog }, { NULL, kModulationQAMAuto }, }; const DTVParamHelperStruct DTVModulation::vdrTable[] = { - { "999", kModulationQAMAuto }, + { "998", kModulationQAMAuto }, { "16", kModulationQAM16 }, { "32", kModulationQAM32 }, { "64", kModulationQAM64 }, { "128", kModulationQAM128 }, { "256", kModulationQAM256 }, - { "0", kModulationQPSK }, + { "2", kModulationQPSK }, + { "5", kModulation8PSK }, + { "6", kModulation16APSK }, + { "7", kModulation32APSK }, + { "10", kModulation8VSB }, + { "11", kModulation16VSB }, { NULL, kModulationQAMAuto }, }; @@ -247,13 +259,10 @@ const DTVParamHelperStruct DTVModulation::parseTable[] = { "qpsk", kModulationQPSK }, { "8vsb", kModulation8VSB }, { "16vsb", kModulation16VSB }, - { "2vsb", kModulation2VSB }, - { "4vsb", kModulation4VSB }, - { "bpsk", kModulationBPSK }, + { "8psk", kModulation8PSK }, { "16apsk", kModulation16APSK }, { "32apsk", kModulation32APSK }, - { "8psk", kModulation8PSK }, - { "16psk", kModulation16PSK }, + { "dqpsk", kModulationDQPSK }, // alternates { "a", kModulationQAMAuto }, { "qam_auto", kModulationQAMAuto }, @@ -265,13 +274,18 @@ const DTVParamHelperStruct DTVModulation::parseTable[] = // qpsk, no alternative { "8-vsb", kModulation8VSB }, { "16-vsb", kModulation16VSB }, - { "2-vsb", kModulation2VSB }, - { "4-vsb", kModulation4VSB }, // bpsk, no alternative { "16-apsk", kModulation16APSK }, { "32-apsk", kModulation32APSK }, { "8-psk", kModulation8PSK }, - { "16-psk", kModulation16PSK }, + // removed modulations and alternatives + { "bpsk", kModulationInvalid }, + { "2vsb", kModulationInvalid }, + { "2-vsb", kModulationInvalid }, + { "4vsb", kModulationInvalid }, + { "4-vsb", kModulationInvalid }, + { "16psk", kModulationInvalid }, + { "16-psk", kModulationInvalid }, { NULL, kModulationQAMAuto }, }; @@ -286,13 +300,10 @@ const char *DTVModulation::dbStr[DTVModulation::kDBStrCnt] = "auto", ///< kModulationQAMAuto "8vsb", ///< kModulation8VSB "16vsb", ///< kModulation16VSB - "2vsb", ///< kModulation2VSB - "4vsb", ///< kModulation4VSB - "bpsk", ///< kModulationBPSK + "8psk", ///< kModulation8PSK "16apsk", ///< kModulation16APSK "32apsk", ///< kModulation32APSK - "8psk", ///< kModulation8PSK - "16psk", ///< kModulation16PSK + "dqpsk" ///< kModulationDQPSK }; const DTVParamHelperStruct DTVTransmitMode::confTable[] = @@ -420,3 +431,64 @@ const char *DTVPolarity::dbStr[DTVPolarity::kDBStrCnt] = "r", ///< kPolarityRight "l" ///< kPolarityLeft }; + +const DTVParamHelperStruct DTVModulationSystem::confTable[] = +{ + { "SYS_DVBS", kModulationSystemDVBS }, + { "SYS_DVBS2", kModulationSystemDVBS2 }, + { NULL, kModulationSystemDVBS }, +}; + +const DTVParamHelperStruct DTVModulationSystem::vdrTable[] = +{ + { "0", kModulationSystemDVBS }, + { "1", kModulationSystemDVBS2 }, + { NULL, kModulationSystemDVBS }, +}; + +const DTVParamHelperStruct DTVModulationSystem::parseTable[] = +{ + { "DVB-S", kModulationSystemDVBS }, + { "DVB-S2", kModulationSystemDVBS2 }, + { NULL, kModulationSystemDVBS }, +}; + +const char *DTVModulationSystem::dbStr[DTVModulationSystem::kDBStrCnt] = +{ + "DVB-S", ///< kModulationSystemDVBS + "DVB-S2", ///< kModulationSystemDVBS2 +}; + +const DTVParamHelperStruct DTVRollOff::confTable[] = +{ + { "ROLLOFF_35", kRollOff_35 }, + { "ROLLOFF_20", kRollOff_20 }, + { "ROLLOFF_25", kRollOff_25 }, + { "ROLLOFF_AUTO", kRollOff_Auto }, + { NULL, kRollOff_35 }, +}; + +const DTVParamHelperStruct DTVRollOff::vdrTable[] = +{ + { "35", kRollOff_35 }, + { "20", kRollOff_20 }, + { "25", kRollOff_25 }, + { "0", kRollOff_Auto }, + { NULL, kRollOff_35 }, +}; +const DTVParamHelperStruct DTVRollOff::parseTable[] = +{ + { "0.35", kRollOff_35 }, + { "0.20", kRollOff_20 }, + { "0.25", kRollOff_25 }, + { "auto", kRollOff_Auto }, + { NULL, kRollOff_35 }, +}; + +const char *DTVRollOff::dbStr[DTVRollOff::kDBStrCnt] = +{ + "0.35", ///< kRollOff_35 + "0.20", ///< kRollOff_20 + "0.25", ///< kRollOff_25 + "auto", ///< kRollOff_Auto +}; diff --git a/mythtv/libs/libmythtv/dtvconfparserhelpers.h b/mythtv/libs/libmythtv/dtvconfparserhelpers.h index c9f3a1c..54a6d8d 100644 --- a/mythtv/libs/libmythtv/dtvconfparserhelpers.h +++ b/mythtv/libs/libmythtv/dtvconfparserhelpers.h @@ -201,7 +201,7 @@ class DTVCodeRate : public DTVParamHelper static const DTVParamHelperStruct confTable[]; static const DTVParamHelperStruct vdrTable[]; static const DTVParamHelperStruct parseTable[]; - static const uint kDBStrCnt = 10; + static const uint kDBStrCnt = 12; static const char *dbStr[kDBStrCnt]; public: @@ -217,6 +217,8 @@ class DTVCodeRate : public DTVParamHelper kFEC_7_8, kFEC_8_9, kFECAuto, + kFEC_3_5, + kFEC_9_10, }; DTVCodeRate(int _default = kFECAuto) : DTVParamHelper(_default) { } @@ -245,29 +247,27 @@ class DTVModulation : public DTVParamHelper static const DTVParamHelperStruct confTable[]; static const DTVParamHelperStruct vdrTable[]; static const DTVParamHelperStruct parseTable[]; - static const uint kDBStrCnt = 17; + static const uint kDBStrCnt = 13; static const char *dbStr[kDBStrCnt]; public: enum { - kModulationQPSK = 0, - kModulationQAM16 = 1, - kModulationQAM32 = 2, - kModulationQAM64 = 3, - kModulationQAM128 = 4, - kModulationQAM256 = 5, - kModulationQAMAuto = 6, - kModulation8VSB = 7, - kModulation16VSB = 8, - kModulation2VSB = 9, - kModulation4VSB = 10, - kModulationBPSK = 11, - kModulation16APSK = 12, - kModulation32APSK = 13, - kModulation8PSK = 14, - kModulation16PSK = 15, - kModulationAnalog = 16, /* for analog channel scanner */ + kModulationQPSK, + kModulationQAM16, + kModulationQAM32, + kModulationQAM64, + kModulationQAM128, + kModulationQAM256, + kModulationQAMAuto, + kModulation8VSB, + kModulation16VSB, + kModulation8PSK, + kModulation16APSK, + kModulation32APSK, + kModulationDQPSK, + kModulationInvalid = 0x100, /* for removed modulations */ + kModulationAnalog = 0x200, /* for analog channel scanner */ }; DTVModulation(int _default = kModulationQAMAuto) @@ -449,4 +449,75 @@ class DTVPolarity : public DTVParamHelper { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); } }; +class DTVModulationSystem : public DTVParamHelper +{ + protected: + static const DTVParamHelperStruct confTable[]; + static const DTVParamHelperStruct vdrTable[]; + static const DTVParamHelperStruct parseTable[]; + static const uint kDBStrCnt = 2; + static const char *dbStr[kDBStrCnt]; + + public: + enum + { + kModulationSystemDVBS, + kModulationSystemDVBS2, + }; + + DTVModulationSystem(int _default = kModulationSystemDVBS) + : DTVParamHelper(_default) { } + + bool ParseConf(const QString &_value) + { return ParseParam(_value, value, confTable); } + bool ParseVDR(const QString &_value) + { return ParseParam(_value, value, vdrTable); } + bool Parse(const QString &_value) + { return ParseParam(_value, value, parseTable); } + + QString toString() const { return toString(value); } + + static QString toString(int _value) + { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); } +}; + +class DTVRollOff : public DTVParamHelper +{ + protected: + static const DTVParamHelperStruct confTable[]; + static const DTVParamHelperStruct vdrTable[]; + static const DTVParamHelperStruct parseTable[]; + static const uint kDBStrCnt = 4; + static const char *dbStr[kDBStrCnt]; + + public: + enum + { + kRollOff_35, + kRollOff_20, + kRollOff_25, + kRollOff_Auto, + }; + + DTVRollOff(int _default = kRollOff_35) + : DTVParamHelper(_default) { } + + bool IsCompatible(const DTVRollOff &other) const + { return value == other.value || value == kRollOff_Auto || + other.value == kRollOff_Auto; + } + + bool ParseConf(const QString &_value) + { return ParseParam(_value, value, confTable); } + bool ParseVDR(const QString &_value) + { return ParseParam(_value, value, vdrTable); } + bool Parse(const QString &_value) + { return ParseParam(_value, value, parseTable); } + + QString toString() const { return toString(value); } + + static QString toString(int _value) + { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); } +}; + #endif // _DTVCONFPARSERHELPERS_H_ diff --git a/mythtv/libs/libmythtv/dtvmultiplex.cpp b/mythtv/libs/libmythtv/dtvmultiplex.cpp index cd1dc81..d226f46 100644 --- a/mythtv/libs/libmythtv/dtvmultiplex.cpp +++ b/mythtv/libs/libmythtv/dtvmultiplex.cpp @@ -22,6 +22,8 @@ DTVMultiplex &DTVMultiplex::operator=(const DTVMultiplex &other) hierarchy = other.hierarchy; polarity = other.polarity; fec = other.fec; + mod_sys = other.mod_sys; + rolloff = other.rolloff; mplex = other.mplex; sistandard = other.sistandard; sistandard.detach(); @@ -39,6 +41,8 @@ bool DTVMultiplex::operator==(const DTVMultiplex &m) const (trans_mode == m.trans_mode) && (guard_interval == m.guard_interval) && (fec == m.fec) && + (mod_sys == m.mod_sys) && + (rolloff == m.rolloff) && (polarity == m.polarity) && (hierarchy == m.hierarchy)); } @@ -56,6 +60,8 @@ QString DTVMultiplex::toString() const .arg(bandwidth.toString()).arg(trans_mode.toString()) .arg(guard_interval.toString()).arg(hierarchy.toString()) .arg(polarity.toString()); + ret += QString(" msys: %1 rolloff: %2") + .arg(mod_sys.toString()).arg(rolloff.toString()); return ret; } @@ -117,17 +123,20 @@ bool DTVMultiplex::IsEqual(DTVTunerType type, const DTVMultiplex &other, if ((DTVTunerType::kTunerTypeDVB_S2 == type) || (DTVTunerType::kTunerTypeQPSK == type)) { + bool ret = + (symbolrate == other.symbolrate) && + (polarity == other.polarity) && + (mod_sys == other.mod_sys); + if (fuzzy) - return + return ret && inversion.IsCompatible(other.inversion) && - (symbolrate == other.symbolrate) && - (polarity == other.polarity) && - fec.IsCompatible(other.fec); - return + fec.IsCompatible(other.fec) && + rolloff.IsCompatible(other.rolloff); + return ret && (inversion == other.inversion) && - (symbolrate == other.symbolrate) && - (polarity == other.polarity) && - (fec == other.fec); + (fec == other.fec) && + (rolloff == other.rolloff); } return false; @@ -220,13 +229,36 @@ bool DTVMultiplex::ParseDVB_S_and_C( return ok; } +bool DTVMultiplex::ParseDVB_S2( + const QString &_frequency, const QString &_inversion, + const QString &_symbol_rate, const QString &_fec_inner, + const QString &_modulation, const QString &_polarity, + const QString &_mod_sys, const QString &_rolloff) +{ + bool ok = ParseDVB_S_and_C(_frequency, _inversion, _symbol_rate, + _fec_inner, _modulation, _polarity); + + if (!mod_sys.Parse(_mod_sys)) + { + VERBOSE(VB_IMPORTANT, LOC_ERR + "Invalid S2 modulation system " + + QString("parameter '%1', aborting.").arg(_mod_sys)); + return false; + } + + if (!_rolloff.isEmpty()) + ok &= rolloff.Parse(_rolloff); + + return ok; +} + bool DTVMultiplex::ParseTuningParams( DTVTunerType type, QString _frequency, QString _inversion, QString _symbolrate, QString _fec, QString _polarity, QString _hp_code_rate, QString _lp_code_rate, QString _ofdm_modulation, QString _trans_mode, QString _guard_interval, QString _hierarchy, - QString _modulation, QString _bandwidth) + QString _modulation, QString _bandwidth, + QString _mod_sys, QString _rolloff) { if (DTVTunerType::kTunerTypeOFDM == type) { @@ -237,7 +269,6 @@ bool DTVMultiplex::ParseTuningParams( } if ((DTVTunerType::kTunerTypeQPSK == type) || - (DTVTunerType::kTunerTypeDVB_S2 == type) || (DTVTunerType::kTunerTypeQAM == type)) { return ParseDVB_S_and_C( @@ -245,6 +276,12 @@ bool DTVMultiplex::ParseTuningParams( _fec, _modulation, _polarity); } + if (DTVTunerType::kTunerTypeDVB_S2 == type) + return ParseDVB_S2( + _frequency, _inversion, _symbolrate, + _fec, _modulation, _polarity, + _mod_sys, _rolloff); + if (DTVTunerType::kTunerTypeATSC == type) return ParseATSC(_frequency, _modulation); @@ -263,7 +300,8 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid) " fec, polarity, " " hp_code_rate, lp_code_rate, constellation, " " transmission_mode, guard_interval, hierarchy, " - " modulation, bandwidth, sistandard " + " modulation, bandwidth, sistandard, " + " mod_sys, rolloff " "FROM dtv_multiplex " "WHERE dtv_multiplex.mplexid = :MPLEXID"); query.bindValue(":MPLEXID", mplexid); @@ -296,7 +334,8 @@ bool DTVMultiplex::FillFromDB(DTVTunerType type, uint mplexid) query.value(6).toString(), query.value(7).toString(), query.value(8).toString(), query.value(9).toString(), query.value(10).toString(), query.value(11).toString(), - query.value(12).toString()); + query.value(12).toString(), query.value(13).toString(), + query.value(14).toString()); } //////////////////////////////////////////////////////////////////////////// @@ -364,6 +403,7 @@ uint ScanDTVTransport::SaveScan(uint scanid) const " symbolrate, fec, polarity, " " hp_code_rate, lp_code_rate, modulation, " " transmission_mode, guard_interval, hierarchy, " + " mod_sys, rolloff, " " bandwidth, sistandard, tuner_type " " ) " "VALUES " @@ -372,6 +412,7 @@ uint ScanDTVTransport::SaveScan(uint scanid) const " :SYMBOLRATE, :FEC, :POLARITY, " " :HP_CODE_RATE, :LP_CODE_RATE, :MODULATION, " " :TRANSMISSION_MODE, :GUARD_INTERVAL, :HIERARCHY, " + " :MOD_SYS, :ROLLOFF, " " :BANDWIDTH, :SISTANDARD, :TUNER_TYPE " " );"); @@ -388,6 +429,8 @@ uint ScanDTVTransport::SaveScan(uint scanid) const query.bindValue(":TRANSMISSION_MODE", trans_mode.toString()); query.bindValue(":GUARD_INTERVAL", guard_interval.toString()); query.bindValue(":HIERARCHY", hierarchy.toString()); + query.bindValue(":MOD_SYS", mod_sys.toString()); + query.bindValue(":ROLLOFF", rolloff.toString()); query.bindValue(":BANDWIDTH", bandwidth.toString()); query.bindValue(":SISTANDARD", sistandard); query.bindValue(":TUNER_TYPE", (uint)tuner_type); @@ -419,7 +462,8 @@ bool ScanDTVTransport::ParseTuningParams( QString _fec, QString _polarity, QString _hp_code_rate, QString _lp_code_rate, QString _ofdm_modulation, QString _trans_mode, QString _guard_interval, QString _hierarchy, - QString _modulation, QString _bandwidth) + QString _modulation, QString _bandwidth, QString _mod_sys, + QString _rolloff) { tuner_type = type; @@ -429,7 +473,8 @@ bool ScanDTVTransport::ParseTuningParams( _fec, _polarity, _hp_code_rate, _lp_code_rate, _ofdm_modulation, _trans_mode, _guard_interval, _hierarchy, - _modulation, _bandwidth); + _modulation, _bandwidth, _mod_sys, + _rolloff); } diff --git a/mythtv/libs/libmythtv/dtvmultiplex.h b/mythtv/libs/libmythtv/dtvmultiplex.h index 0f1d076..db5bcd9 100644 --- a/mythtv/libs/libmythtv/dtvmultiplex.h +++ b/mythtv/libs/libmythtv/dtvmultiplex.h @@ -49,13 +49,20 @@ class DTVMultiplex const QString &symbol_rate, const QString &fec_inner, const QString &modulation, const QString &polarity); + bool ParseDVB_S2( + const QString &frequency, const QString &inversion, + const QString &symbol_rate, const QString &fec_inner, + const QString &modulation, const QString &polarity, + const QString &mod_sys, const QString &rolloff); + bool ParseTuningParams( DTVTunerType type, QString frequency, QString inversion, QString symbolrate, QString fec, QString polarity, QString hp_code_rate, QString lp_code_rate, QString constellation, QString trans_mode, QString guard_interval, QString hierarchy, - QString modulation, QString bandwidth); + QString modulation, QString bandwidth, QString mod_sys, + QString rolloff); QString toString() const; @@ -74,6 +81,8 @@ class DTVMultiplex DTVHierarchy hierarchy; DTVPolarity polarity; DTVCodeRate fec; ///< Inner Forward Error Correction rate + DTVModulationSystem mod_sys; ///< modulation system (only DVB-S or DVB-S2 atm) + DTVRollOff rolloff; // Optional additional info uint mplex; @@ -99,7 +108,8 @@ class ScanDTVTransport : public DTVMultiplex QString fec, QString polarity, QString hp_code_rate, QString lp_code_rate, QString constellation, QString trans_mode, QString guard_interval, QString hierarchy, - QString modulation, QString bandwidth); + QString modulation, QString bandwidth, + QString mod_sys, QString rolloff); public: DTVTunerType tuner_type; diff --git a/mythtv/libs/libmythtv/dvbchannel.cpp b/mythtv/libs/libmythtv/dvbchannel.cpp index 5ed8f60..ed9ff46 100644 --- a/mythtv/libs/libmythtv/dvbchannel.cpp +++ b/mythtv/libs/libmythtv/dvbchannel.cpp @@ -49,10 +49,10 @@ static void drain_dvb_events(int fd); static bool wait_for_backend(int fd, int timeout_ms); -static struct dvb_fe_params dtvmultiplex_to_dvbparams( - DTVTunerType, const DTVMultiplex&); +static struct dvb_frontend_parameters dtvmultiplex_to_dvbparams( + DTVTunerType, const DTVMultiplex&, int intermediate_freq, bool can_fec_auto); static DTVMultiplex dvbparams_to_dtvmultiplex( - DTVTunerType, const dvb_fe_params&); + DTVTunerType, const dvb_frontend_parameters&); #define LOC QString("DVBChan(%1:%2): ").arg(GetCardID()).arg(device) #define LOC_WARN QString("DVBChan(%1:%2) Warning: ") \ @@ -210,49 +210,6 @@ bool DVBChannel::Open(DVBChannel *who) return false; } -#ifdef FE_GET_EXTENDED_INFO - if (info.caps & FE_HAS_EXTENDED_INFO) - { - bool ok = true; - dvb_fe_caps_extended extinfo; - bzero(&extinfo, sizeof(extinfo)); - if (ioctl(fd_frontend, FE_GET_EXTENDED_INFO, &extinfo) < 0) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + - "Failed to get frontend extended information." + ENO); - - ok = false; - } - - if (ok && (extinfo.modulations & MOD_8PSK)) - { - if (ioctl(fd_frontend, FE_SET_STANDARD, FE_DVB_S2) < 0) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + - "Failed to set frontend standard to DVB-S2." + ENO); - - ok = false; - } - else if (ioctl(fd_frontend, FE_GET_INFO, &info) < 0) - { - VERBOSE(VB_IMPORTANT, LOC_ERR + - "Failed to get frontend information." + ENO); - - ok = false; - } - } - - if (!ok) - { - close(fd_frontend); - fd_frontend = -1; - return false; - } - - ext_modulations = extinfo.modulations; - } -#endif - frontend_name = info.name; card_type = info.type; capabilities = info.caps; @@ -596,15 +553,6 @@ bool DVBChannel::CheckModulation(DTVModulation modulation) const const DTVModulation m = modulation; const uint64_t c = capabilities; -#ifdef FE_GET_EXTENDED_INFO - if ((c & FE_HAS_EXTENDED_INFO) && - (DTVModulation::kModulation8PSK == m) && - (ext_modulations & DTVModulation::kModulation8PSK)) - { - return true; - } -#endif // FE_GET_EXTENDED_INFO - return ((DTVModulation::kModulationQPSK == m) && (c & FE_CAN_QPSK)) || ((DTVModulation::kModulationQAM16 == m) && (c & FE_CAN_QAM_16)) || @@ -649,6 +597,91 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning, QString inputname) return Tune(tuning, inputid, false, false); } +#if DVB_API_VERSION >= 5 +static struct dtv_properties *dtvmultiplex_to_dtvproperties( + DTVTunerType tuner_type, const DTVMultiplex &tuning, int intermediate_freq, + bool can_fec_auto, bool do_tune = true) +{ + uint c = 0; + struct dtv_properties *cmdseq = (struct dtv_properties*) calloc(1, sizeof(*cmdseq)); + if (!cmdseq) + return NULL; + + cmdseq->props = (struct dtv_property*) calloc(11, sizeof(*(cmdseq->props))); + if (!(cmdseq->props)) + { + free(cmdseq); + return NULL; + } + + if (tuning.mod_sys == DTVModulationSystem::kModulationSystemDVBS2) + { + cmdseq->props[c].cmd = DTV_DELIVERY_SYSTEM; + cmdseq->props[c++].u.data = SYS_DVBS2; + cmdseq->props[c].cmd = DTV_PILOT; + cmdseq->props[c++].u.data = PILOT_AUTO; + cmdseq->props[c].cmd = DTV_ROLLOFF; + cmdseq->props[c++].u.data = tuning.rolloff; + } + + cmdseq->props[c].cmd = DTV_FREQUENCY; + cmdseq->props[c++].u.data = intermediate_freq ? intermediate_freq : tuning.frequency; + cmdseq->props[c].cmd = DTV_MODULATION; + cmdseq->props[c++].u.data = tuning.modulation; + cmdseq->props[c].cmd = DTV_INVERSION; + cmdseq->props[c++].u.data = tuning.inversion; + + if (tuner_type.IsFECVariable()) + { + cmdseq->props[c].cmd = DTV_INNER_FEC; + cmdseq->props[c++].u.data = can_fec_auto ? FEC_AUTO : tuning.fec; + } + + if (tuner_type == DTVTunerType::kTunerTypeQPSK || + tuner_type == DTVTunerType::kTunerTypeDVB_S2 || + tuner_type == DTVTunerType::kTunerTypeQAM) + { + cmdseq->props[c].cmd = DTV_SYMBOL_RATE; + cmdseq->props[c++].u.data = tuning.symbolrate; + } + else if (tuner_type == DTVTunerType::kTunerTypeOFDM) + { + cmdseq->props[c].cmd = DTV_BANDWIDTH_HZ; + cmdseq->props[c++].u.data = (8-tuning.bandwidth) * 1000000; + cmdseq->props[c].cmd = DTV_CODE_RATE_HP; + cmdseq->props[c++].u.data = tuning.hp_code_rate; + cmdseq->props[c].cmd = DTV_CODE_RATE_LP; + cmdseq->props[c++].u.data = tuning.lp_code_rate; + cmdseq->props[c].cmd = DTV_TRANSMISSION_MODE; + cmdseq->props[c++].u.data = tuning.trans_mode; + cmdseq->props[c].cmd = DTV_GUARD_INTERVAL; + cmdseq->props[c++].u.data = tuning.guard_interval; + cmdseq->props[c].cmd = DTV_HIERARCHY; + cmdseq->props[c++].u.data = tuning.hierarchy; + } + else + { + VERBOSE(VB_IMPORTANT, "Unknown tuner type." + ENO); + return NULL; + } + + if (do_tune) + cmdseq->props[c++].cmd = DTV_TUNE; + + cmdseq->num = c; + +#if 0 + for (int i = 0; i < cmdseq->num; i++) + { + cerr << "prop " << i << ": cmd = " << cmdseq->props[i].cmd + << " data = " << cmdseq->props[i].u.data << endl; + } +#endif + return cmdseq; +} +#endif + + /***************************************************************************** Tuning functions for each of the four types of cards. *****************************************************************************/ @@ -679,8 +712,9 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning, return master->Tune(tuning, inputid, force_reset, false); } + int intermediate_freq = 0; + bool can_fec_auto = false; bool reset = (force_reset || first_tune); - struct dvb_fe_params params = dtvmultiplex_to_dvbparams(card_type, tuning); bool is_dvbs = (DTVTunerType::kTunerTypeQPSK == card_type || DTVTunerType::kTunerTypeDVB_S2 == card_type); @@ -738,12 +772,12 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning, reset = first_tune = true; } - params.frequency = lnb->GetIntermediateFrequency( + intermediate_freq = lnb->GetIntermediateFrequency( diseqc_settings, tuning); // if card can auto-FEC, use it -- sometimes NITs are inaccurate if (capabilities & FE_CAN_FEC_AUTO) - params.u.qpsk.fec_inner = FEC_AUTO; + can_fec_auto = true; } VERBOSE(VB_CHANNEL, LOC + "Old Params: " + @@ -758,21 +792,34 @@ bool DVBChannel::Tune(const DTVMultiplex &tuning, if (reset || !prev_tuning.IsEqual(card_type, tuning, 500 * freq_mult)) { VERBOSE(VB_CHANNEL, LOC + QString("Tune(): Tuning to %1%2") - .arg(params.frequency).arg(suffix)); + .arg(intermediate_freq ? intermediate_freq : tuning.frequency) + .arg(suffix)); -#ifdef FE_GET_EXTENDED_INFO - if (card_type == DTVTunerType::kTunerTypeDVB_S2) +#if DVB_API_VERSION >=5 + if (DTVTunerType::kTunerTypeDVB_S2 == card_type) { - if (ioctl(fd_frontend, FE_SET_FRONTEND2, ¶ms) < 0) + struct dtv_properties *cmds = dtvmultiplex_to_dtvproperties( + card_type, tuning, intermediate_freq, can_fec_auto); + + if (!cmds) + return false; + + if (ioctl(fd_frontend, FE_SET_PROPERTY, cmds) < 0) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): " + - "Setting Frontend(2) tuning parameters failed." + ENO); + "Setting Frontend tuning parameters failed." + ENO); return false; } + free(cmds->props); + free(cmds); } else -#endif // FE_GET_EXTENDED_INFO +#endif { + struct dvb_frontend_parameters params = dtvmultiplex_to_dvbparams(card_type, tuning, + intermediate_freq, + can_fec_auto); + if (ioctl(fd_frontend, FE_SET_FRONTEND, ¶ms) < 0) { VERBOSE(VB_IMPORTANT, LOC_ERR + "Tune(): " + @@ -835,7 +882,7 @@ bool DVBChannel::IsTuningParamsProbeSupported(void) const return false; } - dvb_fe_params params; + dvb_frontend_parameters params; return ioctl(fd_frontend, FE_GET_FRONTEND, ¶ms) >= 0; } @@ -868,7 +915,13 @@ bool DVBChannel::ProbeTuningParams(DTVMultiplex &tuning) const return false; } - dvb_fe_params params; + if (card_type == DTVTunerType::kTunerTypeDVB_S2) + { + // TODO implement probing of tuning parameters with FE_GET_PROPERTY + return false; + } + + dvb_frontend_parameters params; if (ioctl(fd_frontend, FE_GET_FRONTEND, ¶ms) < 0) { VERBOSE(VB_IMPORTANT, LOC_ERR + @@ -1094,10 +1147,11 @@ static bool wait_for_backend(int fd, int timeout_ms) return true; } -static struct dvb_fe_params dtvmultiplex_to_dvbparams( - DTVTunerType tuner_type, const DTVMultiplex &tuning) +static struct dvb_frontend_parameters dtvmultiplex_to_dvbparams( + DTVTunerType tuner_type, const DTVMultiplex &tuning, + int intermediate_freq, bool can_fec_auto) { - dvb_fe_params params; + dvb_frontend_parameters params; bzero(¶ms, sizeof(params)); params.frequency = tuning.frequency; @@ -1105,20 +1159,16 @@ static struct dvb_fe_params dtvmultiplex_to_dvbparams( if (DTVTunerType::kTunerTypeQPSK == tuner_type) { + params.frequency = intermediate_freq; params.u.qpsk.symbol_rate = tuning.symbolrate; - params.u.qpsk.fec_inner = (fe_code_rate_t) (int) tuning.fec; + params.u.qpsk.fec_inner = can_fec_auto ? FEC_AUTO + : (fe_code_rate_t) (int) tuning.fec; } if (DTVTunerType::kTunerTypeDVB_S2 == tuner_type) { -#ifdef FE_GET_EXTENDED_INFO - params.u.qpsk2.symbol_rate = tuning.symbolrate; - params.u.qpsk2.fec_inner = (fe_code_rate_t) (int) tuning.fec; - params.u.qpsk2.modulation = (fe_modulation_t) (int) tuning.modulation; -#else // if !FE_GET_EXTENDED_INFO VERBOSE(VB_IMPORTANT, "DVBChan Error, MythTV was compiled without " "DVB-S2 headers being present so DVB-S2 tuning will fail."); -#endif // !FE_GET_EXTENDED_INFO } if (DTVTunerType::kTunerTypeQAM == tuner_type) @@ -1148,17 +1198,15 @@ static struct dvb_fe_params dtvmultiplex_to_dvbparams( if (DTVTunerType::kTunerTypeATSC == tuner_type) { -#ifdef USE_ATSC params.u.vsb.modulation = (fe_modulation_t) (int) tuning.modulation; -#endif // USE_ATSC } return params; } static DTVMultiplex dvbparams_to_dtvmultiplex( - DTVTunerType tuner_type, const dvb_fe_params ¶ms) + DTVTunerType tuner_type, const dvb_frontend_parameters ¶ms) { DTVMultiplex tuning; @@ -1192,9 +1240,7 @@ static DTVMultiplex dvbparams_to_dtvmultiplex( if (DTVTunerType::kTunerTypeATSC == tuner_type) { -#ifdef USE_ATSC tuning.modulation = params.u.vsb.modulation; -#endif // USE_ATSC } return tuning; diff --git a/mythtv/libs/libmythtv/dvbtypes.h b/mythtv/libs/libmythtv/dvbtypes.h index bc15a22..94a8882 100644 --- a/mythtv/libs/libmythtv/dvbtypes.h +++ b/mythtv/libs/libmythtv/dvbtypes.h @@ -19,30 +19,12 @@ #include #include -#if (DVB_API_VERSION != 3 && DVB_API_VERSION != 5) -# error "DVB driver includes with API version 3 not found!" -#endif - #ifndef DVB_API_VERSION_MINOR -# define DVB_API_VERSION_MINOR 0 -#endif - -#if ((DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR >= 1) || (DVB_API_VERSION > 3)) -# define USE_ATSC -#else -#warning DVB API version < 3.1 -#warning ATSC will not be supported using the Linux DVB drivers -# define FE_ATSC (FE_OFDM+1) -# define FE_CAN_8VSB 0x200000 -# define FE_CAN_16VSB 0x400000 -# define VSB_8 (fe_modulation)(QAM_AUTO+1) -# define VSB_16 (fe_modulation)(QAM_AUTO+2) +#define DVB_API_VERSION_MINOR 0 #endif -#ifdef FE_GET_EXTENDED_INFO - #define dvb_fe_params dvb_frontend_parameters_new -#else - #define dvb_fe_params dvb_frontend_parameters +#if !(DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR >= 1) && DVB_API_VERSION != 5 +# error "DVB driver includes with API version 3.1 or later not found!" #endif class QString; diff --git a/mythtv/libs/libmythtv/frequencytables.cpp b/mythtv/libs/libmythtv/frequencytables.cpp index 6773dd9..e3c940f 100644 --- a/mythtv/libs/libmythtv/frequencytables.cpp +++ b/mythtv/libs/libmythtv/frequencytables.cpp @@ -72,7 +72,8 @@ TransportScanItem::TransportScanItem(uint _sourceid, _tuning.lp_code_rate.toString(), _tuning.modulation.toString(), _tuning.trans_mode.toString(), _tuning.guard_interval.toString(), _tuning.hierarchy.toString(), _tuning.modulation.toString(), - _tuning.bandwidth.toString()); + _tuning.bandwidth.toString(), _tuning.mod_sys.toString(), + _tuning.rolloff.toString()); } TransportScanItem::TransportScanItem(uint sourceid, diff --git a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h index 64a802d..e8fb9e5 100644 --- a/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h +++ b/mythtv/libs/libmythtv/mpeg/dvbdescriptors.h @@ -770,19 +770,40 @@ class SatelliteDeliverySystemDescriptor : public MPEGDescriptor bool IsLinearPolarization() const { return !((_data[8]>>6)&0x1); } bool IsHorizontalLeftPolarization() const { return (_data[8]>>5)&0x1; } bool IsVerticalRightPolarization() const { return !((_data[8]>>5)&0x1); } - // modulation 5 8.3 + // roll off 2 8.3 + enum + { + kRollOff_35, + kRollOff_20, + kRollOff_25, + kRollOff_Auto, + }; + uint RollOff() const { return (_data[8]>>3)&0x3; } + QString RollOffString() const + { + static QString ro[] = { "0.35", "0.20", "0.25", "auto" }; + return ro[RollOff()]; + } + // modulation system 1 8.5 + uint ModulationSystem() const { return (_data[8]>>2)&0x1; } + QString ModulationSystemString() const + { + return ModulationSystem() ? "DVB-S2" : "DVB-S"; + } + // modulation 2 8.6 enum { kModulationQPSK_NS = 0x0, // Non standard QPSK for Bell ExpressVu + // should be "auto" according to DVB SI standard kModulationQPSK = 0x1, kModulation8PSK = 0x2, kModulationQAM16 = 0x3, }; - uint Modulation() const { return _data[8]&0x1f; } + uint Modulation() const { return _data[8]&0x03; } QString ModulationString() const { static QString ms[] = { "qpsk", "qpsk", "8psk", "qam_16" }; - return (Modulation() <= kModulationQAM16) ? ms[Modulation()] : "auto"; + return ms[Modulation()]; } // symbol_rate 28 9.0 uint SymbolRate() const diff --git a/mythtv/libs/libmythtv/scanwizard.cpp b/mythtv/libs/libmythtv/scanwizard.cpp index 1847fdb..c829b36 100644 --- a/mythtv/libs/libmythtv/scanwizard.cpp +++ b/mythtv/libs/libmythtv/scanwizard.cpp @@ -100,6 +100,11 @@ void ScanWizard::SetPage(const QString &pageTitle) start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeQPSK; } + else if (scantype == ScanTypeSetting::NITAddScan_DVBS2) + { + start_chan = configPane->GetStartChan(); + parse_type = DTVTunerType::kTunerTypeDVB_S2; + } else if (scantype == ScanTypeSetting::NITAddScan_DVBC) { start_chan = configPane->GetStartChan(); @@ -162,7 +167,8 @@ void ScanWizard::SetPage(const QString &pageTitle) start_chan["coderate_hp"], start_chan["coderate_lp"], start_chan["constellation"], start_chan["trans_mode"], start_chan["guard_interval"], start_chan["hierarchy"], - start_chan["modulation"], start_chan["bandwidth"])) + start_chan["modulation"], start_chan["bandwidth"], + start_chan["mod_sys"], start_chan["rolloff"])) { MythPopupBox::showOkPopup( gContext->GetMainWindow(), tr("ScanWizard"), diff --git a/mythtv/libs/libmythtv/videosource.cpp b/mythtv/libs/libmythtv/videosource.cpp index bc10656..9b4f3a8 100644 --- a/mythtv/libs/libmythtv/videosource.cpp +++ b/mythtv/libs/libmythtv/videosource.cpp @@ -3341,6 +3341,12 @@ void DVBConfigurationGroup::probeCard(const QString &videodevice) signal_timeout->setValue(60000); channel_timeout->setValue(62500); break; + case CardUtil::DVBS2: + cardtype->setValue("DVB-S2"); + cardname->setValue(frontend_name); + signal_timeout->setValue(60000); + channel_timeout->setValue(62500); + break; case CardUtil::QAM: cardtype->setValue("DVB-C"); cardname->setValue(frontend_name);