bool DTVChannel::TuneMultiplex(uint mplexid, QString inputname) { DTVMultiplex tuning; if (!tuning.FillFromDB(tunerType, mplexid)) return false; CheckOptions(tuning); return Tune(tuning, inputname); }
void DTVConfParser::AddChannel(const DTVMultiplex &mux, DTVChannelInfo &chan) { for (uint i = 0; i < channels.size(); i++) { if (channels[i] == mux) { channels[i].channels.push_back(chan); VERBOSE(VB_IMPORTANT, "Imported channel: "<<chan.toString() <<" on "<<mux.toString()); return; } } channels.push_back(mux); channels.back().channels.push_back(chan); VERBOSE(VB_IMPORTANT, "Imported channel: "<<chan.toString() <<" on "<<mux.toString()); }
/** * \brief Tunes the card to a frequency but does not deal with PIDs. * * This is used by DVB Channel Scanner, the EIT Parser, and by TVRec. * * \param tuning Info on transport to tune to * \param inputid Optional, forces specific input (for DiSEqC) * \param force_reset If true, frequency tuning is done * even if it should not be needed. * \param same_input Optional, doesn't change input (for retuning). * \return true on success, false on failure */ bool DVBChannel::Tune(const DTVMultiplex &tuning, uint inputid, bool force_reset, bool same_input) { QMutexLocker lock(&tune_lock); QMutexLocker locker(&hw_lock); DVBChannel *master = GetMasterLock(); if (master != this) { LOG(VB_CHANNEL, LOG_INFO, LOC + "tuning on slave channel"); SetSIStandard(tuning.sistandard); bool ok = master->Tune(tuning, inputid, force_reset, false); ReturnMasterLock(master); return ok; } ReturnMasterLock(master); // if we're the master we don't need this lock.. int intermediate_freq = 0; bool can_fec_auto = false; bool reset = (force_reset || first_tune); if (tunerType.IsDiSEqCSupported() && !diseqc_tree) { LOG(VB_GENERAL, LOG_ERR, LOC + "DVB-S needs device tree for LNB handling"); return false; } desired_tuning = tuning; if (fd_frontend < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Tune(): Card not open!"); return false; } // Remove any events in queue before tuning. drain_dvb_events(fd_frontend); // send DVB-S setup if (diseqc_tree) { // configure for new input if (!same_input) diseqc_settings.Load(inputid); // execute diseqc commands if (!diseqc_tree->Execute(diseqc_settings, tuning)) { LOG(VB_GENERAL, LOG_ERR, LOC + "Tune(): Failed to setup DiSEqC devices"); return false; } // retrieve actual intermediate frequency DiSEqCDevLNB *lnb = diseqc_tree->FindLNB(diseqc_settings); if (!lnb) { LOG(VB_GENERAL, LOG_ERR, LOC + "Tune(): No LNB for this configuration"); return false; } if (lnb->GetDeviceID() != last_lnb_dev_id) { last_lnb_dev_id = lnb->GetDeviceID(); // make sure we tune to frequency, if the lnb has changed reset = first_tune = true; } intermediate_freq = lnb->GetIntermediateFrequency( diseqc_settings, tuning); // if card can auto-FEC, use it -- sometimes NITs are inaccurate if (capabilities & FE_CAN_FEC_AUTO) can_fec_auto = true; // Check DVB-S intermediate frequency here since it requires a fully // initialized diseqc tree CheckFrequency(intermediate_freq); } LOG(VB_CHANNEL, LOG_INFO, LOC + "Old Params: " + prev_tuning.toString() + "\n\t\t\t" + LOC + "New Params: " + tuning.toString()); // DVB-S is in kHz, other DVB is in Hz bool is_dvbs = ((DTVTunerType::kTunerTypeDVBS1 == tunerType) || (DTVTunerType::kTunerTypeDVBS2 == tunerType)); int freq_mult = (is_dvbs) ? 1 : 1000; QString suffix = (is_dvbs) ? "kHz" : "Hz"; if (reset || !prev_tuning.IsEqual(tunerType, tuning, 500 * freq_mult)) { LOG(VB_CHANNEL, LOG_INFO, LOC + QString("Tune(): Tuning to %1%2") .arg(intermediate_freq ? intermediate_freq : tuning.frequency) .arg(suffix)); #if DVB_API_VERSION >=5 if (DTVTunerType::kTunerTypeDVBS2 == tunerType) { struct dtv_property p_clear; struct dtv_properties cmdseq_clear; p_clear.cmd = DTV_CLEAR; cmdseq_clear.num = 1; cmdseq_clear.props = &p_clear; if ((ioctl(fd_frontend, FE_SET_PROPERTY, &cmdseq_clear)) < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Tune(): Clearing DTV properties cache failed." + ENO); return false; } struct dtv_properties *cmds = dtvmultiplex_to_dtvproperties( tunerType, tuning, intermediate_freq, can_fec_auto); if (!cmds) { LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to convert DTVMultiplex to DTV_PROPERTY sequence"); return false; } if (VERBOSE_LEVEL_CHECK(VB_CHANNEL, LOG_DEBUG)) { for (uint i = 0; i < cmds->num; i++) { LOG(VB_CHANNEL, LOG_DEBUG, LOC + QString("prop %1: cmd = %2, data %3") .arg(i).arg(cmds->props[i].cmd) .arg(cmds->props[i].u.data)); } } int res = ioctl(fd_frontend, FE_SET_PROPERTY, cmds); free(cmds->props); free(cmds); if (res < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Tune(): Setting Frontend tuning parameters failed." + ENO); return false; } } else #endif { struct dvb_frontend_parameters params = dtvmultiplex_to_dvbparams( tunerType, tuning, intermediate_freq, can_fec_auto); if (ioctl(fd_frontend, FE_SET_FRONTEND, ¶ms) < 0) { LOG(VB_GENERAL, LOG_ERR, LOC + "Tune(): Setting Frontend tuning parameters failed." + ENO); return false; } } // Extra delay to add for broken DVB drivers if (tuning_delay) usleep(tuning_delay * 1000); wait_for_backend(fd_frontend, 5 /* msec */); prev_tuning = tuning; first_tune = false; } SetSIStandard(tuning.sistandard); LOG(VB_CHANNEL, LOG_INFO, LOC + "Tune(): Frequency tuning successful."); return true; }
void DVBChannel::CheckOptions(DTVMultiplex &tuning) const { if ((tuning.inversion == DTVInversion::kInversionAuto) && !(capabilities & FE_CAN_INVERSION_AUTO)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "'Auto' inversion parameter unsupported by this driver, " "falling back to 'off'."); tuning.inversion = DTVInversion::kInversionOff; } // DVB-S needs a fully initialized diseqc tree and is checked later in Tune if (!diseqc_tree) CheckFrequency(tuning.frequency); if (tunerType.IsFECVariable() && symbol_rate_minimum && symbol_rate_maximum && (symbol_rate_minimum <= symbol_rate_maximum) && (tuning.symbolrate < symbol_rate_minimum || tuning.symbolrate > symbol_rate_maximum)) { LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Symbol Rate setting (%1) is out of range (min/max:%2/%3)") .arg(tuning.symbolrate) .arg(symbol_rate_minimum).arg(symbol_rate_maximum)); } if (tunerType.IsFECVariable() && !CheckCodeRate(tuning.fec)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Selected fec_inner parameter unsupported by this driver."); } if (tunerType.IsModulationVariable() && !CheckModulation(tuning.modulation)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Selected modulation parameter unsupported by this driver."); } if (DTVTunerType::kTunerTypeDVBT != tunerType) { LOG(VB_CHANNEL, LOG_INFO, LOC + tuning.toString()); return; } // Check OFDM Tuning params if (!CheckCodeRate(tuning.hp_code_rate)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Selected code_rate_hp parameter unsupported by this driver."); } if (!CheckCodeRate(tuning.lp_code_rate)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Selected code_rate_lp parameter unsupported by this driver."); } if ((tuning.bandwidth == DTVBandwidth::kBandwidthAuto) && !(capabilities & FE_CAN_BANDWIDTH_AUTO)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "'Auto' bandwidth parameter unsupported by this driver."); } if ((tuning.trans_mode == DTVTransmitMode::kTransmissionModeAuto) && !(capabilities & FE_CAN_TRANSMISSION_MODE_AUTO)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "'Auto' transmission_mode parameter unsupported by this driver."); } if ((tuning.guard_interval == DTVGuardInterval::kGuardIntervalAuto) && !(capabilities & FE_CAN_GUARD_INTERVAL_AUTO)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "'Auto' guard_interval parameter unsupported by this driver."); } if ((tuning.hierarchy == DTVHierarchy::kHierarchyAuto) && !(capabilities & FE_CAN_HIERARCHY_AUTO)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "'Auto' hierarchy parameter unsupported by this driver. "); } if (!CheckModulation(tuning.modulation)) { LOG(VB_GENERAL, LOG_WARNING, LOC + "Selected modulation parameter unsupported by this driver."); } LOG(VB_CHANNEL, LOG_INFO, LOC + tuning.toString()); }
bool DTVChannel::SetChannelByString(const QString &channum) { QString loc = LOC + QString("SetChannelByString(%1): ").arg(channum); LOG(VB_CHANNEL, LOG_INFO, loc); ClearDTVInfo(); if (!IsOpen() && !Open()) { LOG(VB_GENERAL, LOG_ERR, loc + "Channel object " "will not open, can not change channels."); return false; } if (m_inputs.size() > 1) { QString inputName; if (!CheckChannel(channum, inputName)) { LOG(VB_GENERAL, LOG_ERR, loc + "CheckChannel failed.\n\t\t\tPlease verify the channel " "in the 'mythtv-setup' Channel Editor."); return false; } // If CheckChannel filled in the inputName then we need to // change inputs and return, since the act of changing // inputs will change the channel as well. if (!inputName.isEmpty()) return SwitchToInput(inputName, channum); } InputMap::const_iterator it = m_inputs.find(m_currentInputID); if (it == m_inputs.end()) return false; uint mplexid_restriction; if (!IsInputAvailable(m_currentInputID, mplexid_restriction)) { LOG(VB_GENERAL, LOG_INFO, loc + QString("Requested channel '%1' is on input '%2' " "which is in a busy input group") .arg(channum).arg(m_currentInputID)); return false; } // Fetch tuning data from the database. QString tvformat, modulation, freqtable, freqid, si_std; int finetune; uint64_t frequency; int mpeg_prog_num; uint atsc_major, atsc_minor, mplexid, tsid, netid; if (!ChannelUtil::GetChannelData( (*it)->sourceid, channum, tvformat, modulation, freqtable, freqid, finetune, frequency, si_std, mpeg_prog_num, atsc_major, atsc_minor, tsid, netid, mplexid, m_commfree)) { LOG(VB_GENERAL, LOG_ERR, loc + "Unable to find channel in database."); return false; } if (mplexid_restriction && (mplexid != mplexid_restriction)) { LOG(VB_GENERAL, LOG_ERR, loc + QString("Requested channel '%1' is not available because " "the tuner is currently in use on another transport.") .arg(channum)); return false; } // If the frequency is zeroed out, don't use it directly. if (frequency == 0) { frequency = (freqid.toUInt() + finetune) * 1000; mplexid = 0; } bool isFrequency = (frequency > 10000000); bool hasTuneToChan = !(*it)->tuneToChannel.isEmpty() && (*it)->tuneToChannel != "Undefined"; // If we are tuning to a freqid, rather than an actual frequency, // we may need to set the frequency table to use. if (!isFrequency || hasTuneToChan) SetFreqTable(freqtable); // Set NTSC, PAL, ATSC, etc. SetFormat(tvformat); // If a tuneToChannel is set make sure we're still on it if (hasTuneToChan) Tune((*it)->tuneToChannel, 0); // Clear out any old PAT or PMT & save version info uint version = 0; if (genPAT) { version = (genPAT->Version()+1) & 0x1f; delete genPAT; genPAT = NULL; delete genPMT; genPMT = NULL; } bool ok = true; if ((*it)->externalChanger.isEmpty()) { if (IsIPTV()) { int chanid = ChannelUtil::GetChanID((*it)->sourceid, channum); IPTVTuningData tuning = ChannelUtil::GetIPTVTuningData(chanid); if (!Tune(tuning)) { LOG(VB_GENERAL, LOG_ERR, loc + "Tuning to IPTV URL"); ClearDTVInfo(); ok = false; } } else if ((*it)->name.contains("composite", Qt::CaseInsensitive) || (*it)->name.contains("s-video", Qt::CaseInsensitive)) { LOG(VB_GENERAL, LOG_WARNING, loc + "You have not set " "an external channel changing" "\n\t\t\tscript for a composite or s-video " "input. Channel changing will do nothing."); } else if (isFrequency && Tune(frequency, "")) { } else if (isFrequency) { // Initialize basic the tuning parameters DTVMultiplex tuning; if (!mplexid || !tuning.FillFromDB(tunerType, mplexid)) { LOG(VB_GENERAL, LOG_ERR, loc + "Failed to initialize multiplex options"); ok = false; } else { // Try to fix any problems with the multiplex CheckOptions(tuning); // Tune to proper multiplex if (!Tune(tuning, (*it)->name)) { LOG(VB_GENERAL, LOG_ERR, loc + "Tuning to frequency."); ClearDTVInfo(); ok = false; } } } else { ok = Tune(freqid, finetune); } } LOG(VB_CHANNEL, LOG_INFO, loc + ((ok) ? "success" : "failure")); if (!ok) return false; if (atsc_minor || (mpeg_prog_num>=0)) { SetSIStandard(si_std); SetDTVInfo(atsc_major, atsc_minor, netid, tsid, mpeg_prog_num); } else if (IsPIDTuningSupported()) { // We need to pull the pid_cache since there are no tuning tables pid_cache_t pid_cache; int chanid = ChannelUtil::GetChanID((*it)->sourceid, channum); ChannelUtil::GetCachedPids(chanid, pid_cache); if (pid_cache.empty()) { LOG(VB_GENERAL, LOG_ERR, loc + "PID cache is empty"); return false; } // Now we construct the PAT & PMT vector<uint> pnum; pnum.push_back(1); vector<uint> pid; pid.push_back(9999); genPAT = ProgramAssociationTable::Create(0,version,pnum,pid); int pcrpid = -1; vector<uint> pids; vector<uint> types; pid_cache_t::iterator pit = pid_cache.begin(); for (; pit != pid_cache.end(); ++pit) { if (!pit->GetStreamID()) continue; pids.push_back(pit->GetPID()); types.push_back(pit->GetStreamID()); if (pit->IsPCRPID()) pcrpid = pit->GetPID(); if ((pcrpid < 0) && StreamID::IsVideo(pit->GetStreamID())) pcrpid = pit->GetPID(); } if (pcrpid < 0) pcrpid = pid_cache[0].GetPID(); genPMT = ProgramMapTable::Create( pnum.back(), pid.back(), pcrpid, version, pids, types); SetSIStandard("mpeg"); SetDTVInfo(0,0,0,0,-1); } // Set the current channum to the new channel's channum m_curchannelname = channum; // Setup filters & recording picture attributes for framegrabing recorders // now that the new curchannelname has been established. if (m_pParent) m_pParent->SetVideoFiltersForChannel(GetCurrentSourceID(), channum); InitPictureAttributes(); HandleScript(freqid); return ok; }
void ScanWizard::SetPage(const QString &pageTitle) { VERBOSE(VB_SIPARSER, QString("SetPage(%1)").arg(pageTitle)); if (pageTitle != ScanWizardScanner::kTitle) return; QMap<QString,QString> start_chan; DTVTunerType parse_type = DTVTunerType::kTunerTypeUnknown; uint cardid = configPane->GetCardID(); QString inputname = configPane->GetInputName(); uint sourceid = configPane->GetSourceID(); int scantype = configPane->GetScanType(); bool do_scan = true; VERBOSE(VB_SIPARSER, LOC + "SetPage(): " + QString("type(%1) cardid(%2) inputname(%3)") .arg(scantype).arg(cardid).arg(inputname)); if (scantype == ScanTypeSetting::DVBUtilsImport) { scannerPane->ImportDVBUtils(sourceid, lastHWCardType, configPane->GetFilename()); } else if (scantype == ScanTypeSetting::NITAddScan_OFDM) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeOFDM; } else if (scantype == ScanTypeSetting::NITAddScan_QPSK) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeQPSK; } else if (scantype == ScanTypeSetting::NITAddScan_QAM) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeQAM; } else if (scantype == ScanTypeSetting::IPTVImport) { do_scan = false; scannerPane->ImportM3U(cardid, inputname, sourceid); } else if ((scantype == ScanTypeSetting::FullScan_ATSC) || (scantype == ScanTypeSetting::FullTransportScan) || (scantype == ScanTypeSetting::TransportScan) || (scantype == ScanTypeSetting::FullScan_OFDM) || (scantype == ScanTypeSetting::FullScan_Analog)) { ; } else { do_scan = false; VERBOSE(VB_SIPARSER, LOC_ERR + "SetPage(): " + QString("type(%1) src(%2) cardid(%3) not handled") .arg(scantype).arg(sourceid).arg(cardid)); MythPopupBox::showOkPopup( gContext->GetMainWindow(), tr("ScanWizard"), "Programmer Error, see console"); } // Just verify what we get from the UI... DTVMultiplex tuning; if ((DTVTunerType::kTunerTypeUnknown != parse_type) && !tuning.ParseTuningParams( parse_type, start_chan["frequency"], start_chan["inversion"], start_chan["symbolrate"], start_chan["fec"], start_chan["polarity"], 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"])) { MythPopupBox::showOkPopup( gContext->GetMainWindow(), tr("ScanWizard"), tr("Error parsing parameters")); do_scan = false; } if (do_scan) { scannerPane->Scan( configPane->GetScanType(), configPane->GetCardID(), configPane->GetInputName(), configPane->GetSourceID(), configPane->DoDeleteChannels(), configPane->DoRenameChannels(), configPane->DoIgnoreSignalTimeout(), configPane->GetMultiplex(), start_chan, configPane->GetFrequencyStandard(), configPane->GetModulation(), configPane->GetFrequencyTable(), configPane->GetATSCFormat()); } }
bool DVBChannel::SetChannelByString(const QString &channum) { QString tmp = QString("SetChannelByString(%1): ").arg(channum); QString loc = LOC + tmp; QString loc_err = LOC_ERR + tmp; VERBOSE(VB_CHANNEL, loc); if (!IsOpen()) { VERBOSE(VB_IMPORTANT, loc_err + "Channel object " "will not open, cannot change channels."); ClearDTVInfo(); return false; } ClearDTVInfo(); QString inputName; if (!CheckChannel(channum, inputName)) { VERBOSE(VB_IMPORTANT, loc_err + "CheckChannel failed.\n\t\t\tPlease verify the channel " "in the 'mythtv-setup' Channel Editor."); return false; } // If CheckChannel filled in the inputName we need to change inputs. if (!inputName.isEmpty() && (nextInputID == m_currentInputID)) nextInputID = GetInputByName(inputName); // Get the input data for the channel int inputid = (nextInputID >= 0) ? nextInputID : m_currentInputID; InputMap::const_iterator it = m_inputs.find(inputid); if (it == m_inputs.end()) return false; uint mplexid_restriction; if (!IsInputAvailable(inputid, mplexid_restriction)) { VERBOSE(VB_IMPORTANT, loc_err + "Input is not available"); return false; } // Get the input data for the channel QString tvformat, modulation, freqtable, freqid, si_std; int finetune; uint64_t frequency; int mpeg_prog_num; uint atsc_major, atsc_minor, mplexid, tsid, netid; if (!ChannelUtil::GetChannelData( (*it)->sourceid, channum, tvformat, modulation, freqtable, freqid, finetune, frequency, si_std, mpeg_prog_num, atsc_major, atsc_minor, tsid, netid, mplexid, m_commfree)) { VERBOSE(VB_IMPORTANT, loc_err + "Unable to find channel in database."); return false; } if (mplexid_restriction && (mplexid != mplexid_restriction)) { VERBOSE(VB_IMPORTANT, loc_err + "Multiplex is not available"); return false; } // Initialize basic the tuning parameters DTVMultiplex tuning; if (!mplexid || !tuning.FillFromDB(tunerType, mplexid)) { VERBOSE(VB_IMPORTANT, loc_err + "Failed to initialize multiplex options"); return false; } SetDTVInfo(atsc_major, atsc_minor, netid, tsid, mpeg_prog_num); // Try to fix any problems with the multiplex CheckOptions(tuning); if (!Tune(tuning, inputid)) { VERBOSE(VB_IMPORTANT, loc_err + "Tuning to frequency."); ClearDTVInfo(); return false; } QString tmpX = channum; tmpX.detach(); m_curchannelname = tmpX; VERBOSE(VB_CHANNEL, loc + "Tuned to frequency."); m_currentInputID = nextInputID; QString tmpY = m_curchannelname; tmpY.detach(); m_inputs[m_currentInputID]->startChanNum = tmpY; return true; }
void ScanWizard::SetPage(const QString &pageTitle) { LOG(VB_CHANSCAN, LOG_INFO, QString("SetPage(%1)").arg(pageTitle)); if (pageTitle != ChannelScannerGUI::kTitle) { scannerPane->quitScanning(); return; } QMap<QString,QString> start_chan; DTVTunerType parse_type = DTVTunerType::kTunerTypeUnknown; uint cardid = configPane->GetCardID(); QString inputname = configPane->GetInputName(); uint sourceid = configPane->GetSourceID(); int scantype = configPane->GetScanType(); bool do_scan = true; LOG(VB_CHANSCAN, LOG_INFO, LOC + "SetPage(): " + QString("type(%1) cardid(%2) inputname(%3)") .arg(scantype).arg(cardid).arg(inputname)); if (scantype == ScanTypeSetting::DVBUtilsImport) { scannerPane->ImportDVBUtils(sourceid, lastHWCardType, configPane->GetFilename()); } else if (scantype == ScanTypeSetting::NITAddScan_DVBT) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBT; } else if (scantype == ScanTypeSetting::NITAddScan_DVBS) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBS1; } else if (scantype == ScanTypeSetting::NITAddScan_DVBS2) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBS2; } else if (scantype == ScanTypeSetting::NITAddScan_DVBC) { start_chan = configPane->GetStartChan(); parse_type = DTVTunerType::kTunerTypeDVBC; } else if (scantype == ScanTypeSetting::IPTVImport) { do_scan = false; scannerPane->ImportM3U(cardid, inputname, sourceid); } else if ((scantype == ScanTypeSetting::FullScan_ATSC) || (scantype == ScanTypeSetting::FullTransportScan) || (scantype == ScanTypeSetting::TransportScan) || (scantype == ScanTypeSetting::CurrentTransportScan) || (scantype == ScanTypeSetting::FullScan_DVBC) || (scantype == ScanTypeSetting::FullScan_DVBT) || (scantype == ScanTypeSetting::FullScan_Analog)) { ; } else if (scantype == ScanTypeSetting::ExistingScanImport) { do_scan = false; uint scanid = configPane->GetScanID(); ScanDTVTransportList transports = LoadScan(scanid); ChannelImporter ci(true, true, true, true, false, configPane->DoFreeToAirOnly(), configPane->GetServiceRequirements()); ci.Process(transports); } else { do_scan = false; LOG(VB_CHANSCAN, LOG_ERR, LOC + "SetPage(): " + QString("type(%1) src(%2) cardid(%3) not handled") .arg(scantype).arg(sourceid).arg(cardid)); MythPopupBox::showOkPopup( GetMythMainWindow(), tr("ScanWizard"), tr("Programmer Error, see console")); } // Just verify what we get from the UI... DTVMultiplex tuning; if ((parse_type != DTVTunerType::kTunerTypeUnknown) && !tuning.ParseTuningParams( parse_type, start_chan["frequency"], start_chan["inversion"], start_chan["symbolrate"], start_chan["fec"], start_chan["polarity"], 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["mod_sys"], start_chan["rolloff"])) { MythPopupBox::showOkPopup( GetMythMainWindow(), tr("ScanWizard"), tr("Error parsing parameters")); do_scan = false; } if (do_scan) { QString table_start, table_end; configPane->GetFrequencyTableRange(table_start, table_end); scannerPane->Scan( configPane->GetScanType(), configPane->GetCardID(), configPane->GetInputName(), configPane->GetSourceID(), configPane->DoIgnoreSignalTimeout(), configPane->DoFollowNIT(), configPane->DoTestDecryption(), configPane->DoFreeToAirOnly(), configPane->GetServiceRequirements(), // stuff needed for particular scans configPane->GetMultiplex(), start_chan, configPane->GetFrequencyStandard(), configPane->GetModulation(), configPane->GetFrequencyTable(), table_start, table_end); } }