00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <algorithm>
00031 using namespace std;
00032
00033 #include "analogsignalmonitor.h"
00034 #include "iptvchannelfetcher.h"
00035 #include "dvbsignalmonitor.h"
00036 #include "scanwizardconfig.h"
00037 #include "channelscan_sm.h"
00038 #include "channelscanner.h"
00039 #include "hdhrchannel.h"
00040 #include "scanmonitor.h"
00041 #include "asichannel.h"
00042 #include "dvbchannel.h"
00043 #include "v4lchannel.h"
00044 #include "cardutil.h"
00045
00046 #define LOC QString("ChScan: ")
00047
00048 ChannelScanner::ChannelScanner() :
00049 scanMonitor(NULL), channel(NULL), sigmonScanner(NULL), freeboxScanner(NULL),
00050 freeToAirOnly(false), serviceRequirements(kRequireAV)
00051 {
00052 }
00053
00054 ChannelScanner::~ChannelScanner()
00055 {
00056 Teardown();
00057
00058 if (scanMonitor)
00059 {
00060 scanMonitor->deleteLater();
00061 scanMonitor = NULL;
00062 }
00063 }
00064
00065 void ChannelScanner::Teardown(void)
00066 {
00067 if (sigmonScanner)
00068 {
00069 delete sigmonScanner;
00070 sigmonScanner = NULL;
00071 }
00072
00073 if (channel)
00074 {
00075 delete channel;
00076 channel = NULL;
00077 }
00078
00079 #ifdef USING_IPTV
00080 if (freeboxScanner)
00081 {
00082 freeboxScanner->Stop();
00083 delete freeboxScanner;
00084 freeboxScanner = NULL;
00085 }
00086 #endif // USING_IPTV
00087
00088 if (scanMonitor)
00089 {
00090 scanMonitor->deleteLater();
00091 scanMonitor = NULL;
00092 }
00093 }
00094
00095
00096
00097 void ChannelScanner::Scan(
00098 int scantype,
00099 uint cardid,
00100 const QString &inputname,
00101 uint sourceid,
00102 bool do_ignore_signal_timeout,
00103 bool do_follow_nit,
00104 bool do_test_decryption,
00105 bool do_fta_only,
00106 ServiceRequirements service_requirements,
00107
00108 uint mplexid ,
00109 const QMap<QString,QString> &startChan ,
00110 const QString &freq_std ,
00111 const QString &mod ,
00112 const QString &tbl ,
00113 const QString &tbl_start ,
00114 const QString &tbl_end )
00115 {
00116 freeToAirOnly = do_fta_only;
00117 serviceRequirements = service_requirements;
00118
00119 PreScanCommon(scantype, cardid, inputname,
00120 sourceid, do_ignore_signal_timeout, do_test_decryption);
00121
00122 LOG(VB_CHANSCAN, LOG_INFO, LOC + "Scan()");
00123
00124 if (!sigmonScanner)
00125 {
00126 LOG(VB_CHANSCAN, LOG_ERR, LOC + "Scan(): scanner does not exist...");
00127 return;
00128 }
00129
00130 sigmonScanner->StartScanner();
00131 scanMonitor->ScanUpdateStatusText("");
00132
00133 bool ok = false;
00134
00135 if ((ScanTypeSetting::FullScan_ATSC == scantype) ||
00136 (ScanTypeSetting::FullScan_DVBC == scantype) ||
00137 (ScanTypeSetting::FullScan_DVBT == scantype) ||
00138 (ScanTypeSetting::FullScan_Analog == scantype))
00139 {
00140 LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("ScanTransports(%1, %2, %3)")
00141 .arg(freq_std).arg(mod).arg(tbl));
00142
00143
00144
00145 if ((mod.left(3).toLower() == "qam") &&
00146 (sigmonScanner->GetSignalTimeout() < 1000))
00147 {
00148 sigmonScanner->SetSignalTimeout(1000);
00149 }
00150
00151
00152 sigmonScanner->SetAnalog(ScanTypeSetting::FullScan_Analog == scantype);
00153
00154 ok = sigmonScanner->ScanTransports(
00155 sourceid, freq_std, mod, tbl, tbl_start, tbl_end);
00156 }
00157 else if ((ScanTypeSetting::NITAddScan_DVBT == scantype) ||
00158 (ScanTypeSetting::NITAddScan_DVBS == scantype) ||
00159 (ScanTypeSetting::NITAddScan_DVBS2 == scantype) ||
00160 (ScanTypeSetting::NITAddScan_DVBC == scantype))
00161 {
00162 LOG(VB_CHANSCAN, LOG_INFO, LOC + "ScanTransports()");
00163
00164 ok = sigmonScanner->ScanTransportsStartingOn(sourceid, startChan);
00165 }
00166 else if (ScanTypeSetting::FullTransportScan == scantype)
00167 {
00168 LOG(VB_CHANSCAN, LOG_INFO, LOC + QString("ScanExistingTransports(%1)")
00169 .arg(sourceid));
00170
00171 ok = sigmonScanner->ScanExistingTransports(sourceid, do_follow_nit);
00172 if (ok)
00173 {
00174 scanMonitor->ScanPercentComplete(0);
00175 }
00176 else
00177 {
00178 InformUser(QObject::tr("Error tuning to transport"));
00179 Teardown();
00180 }
00181 }
00182 else if ((ScanTypeSetting::DVBUtilsImport == scantype) && channels.size())
00183 {
00184 ok = true;
00185
00186 LOG(VB_CHANSCAN, LOG_INFO, LOC +
00187 QString("ScanForChannels(%1)").arg(sourceid));
00188
00189 QString card_type = CardUtil::GetRawCardType(cardid);
00190 QString sub_type = card_type;
00191 if (card_type == "DVB")
00192 {
00193 QString device = CardUtil::GetVideoDevice(cardid);
00194
00195 ok = !device.isEmpty();
00196 if (ok)
00197 sub_type = CardUtil::ProbeDVBType(device).toUpper();
00198 }
00199
00200 if (ok)
00201 {
00202 ok = sigmonScanner->ScanForChannels(sourceid, freq_std,
00203 sub_type, channels);
00204 }
00205 if (ok)
00206 {
00207 scanMonitor->ScanPercentComplete(0);
00208 }
00209 else
00210 {
00211 InformUser(QObject::tr("Error tuning to transport"));
00212 Teardown();
00213 }
00214 }
00215 else if (ScanTypeSetting::TransportScan == scantype)
00216 {
00217 LOG(VB_CHANSCAN, LOG_INFO, LOC +
00218 QString("ScanTransport(%1)").arg(mplexid));
00219
00220 ok = sigmonScanner->ScanTransport(mplexid, do_follow_nit);
00221 }
00222 else if (ScanTypeSetting::CurrentTransportScan == scantype)
00223 {
00224 QString sistandard = "mpeg";
00225 LOG(VB_CHANSCAN, LOG_INFO, LOC +
00226 "ScanCurrentTransport(" + sistandard + ")");
00227 ok = sigmonScanner->ScanCurrentTransport(sistandard);
00228 }
00229
00230 if (!ok)
00231 {
00232 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to handle tune complete.");
00233 InformUser(QObject::tr("Programmer Error: "
00234 "Failed to handle tune complete."));
00235 }
00236 }
00237
00238 DTVConfParser::return_t ChannelScanner::ImportDVBUtils(
00239 uint sourceid, int cardtype, const QString &file)
00240 {
00241 channels.clear();
00242
00243 DTVConfParser::cardtype_t type = DTVConfParser::UNKNOWN;
00244 type = (CardUtil::DVBT == cardtype) ? DTVConfParser::OFDM : type;
00245 type = (CardUtil::QPSK == cardtype) ? DTVConfParser::QPSK : type;
00246 type = (CardUtil::DVBC == cardtype) ? DTVConfParser::QAM : type;
00247 type = (CardUtil::DVBS2 == cardtype) ? DTVConfParser::DVBS2 : type;
00248 type = ((CardUtil::ATSC == cardtype) ||
00249 (CardUtil::HDHOMERUN == cardtype)) ? DTVConfParser::ATSC : type;
00250
00251 DTVConfParser::return_t ret = DTVConfParser::OK;
00252 if (type == DTVConfParser::UNKNOWN)
00253 ret = DTVConfParser::ERROR_CARDTYPE;
00254 else
00255 {
00256 DTVConfParser parser(type, sourceid, file);
00257
00258 ret = parser.Parse();
00259 if (DTVConfParser::OK == ret)
00260 channels = parser.GetChannels();
00261 }
00262
00263 if (DTVConfParser::OK != ret)
00264 {
00265 QString msg = (DTVConfParser::ERROR_PARSE == ret) ?
00266 QObject::tr("Failed to parse '%1'") :
00267 ((DTVConfParser::ERROR_CARDTYPE == ret) ?
00268 QString("Programmer Error : incorrect card type") :
00269 QObject::tr("Failed to open '%1'"));
00270
00271 InformUser(msg);
00272 }
00273
00274 return ret;
00275 }
00276
00277 bool ChannelScanner::ImportM3U(
00278 uint cardid, const QString &inputname, uint sourceid)
00279 {
00280 (void) cardid;
00281 (void) inputname;
00282 (void) sourceid;
00283 bool ok = false;
00284
00285 #ifdef USING_IPTV
00286
00287 freeboxScanner = new IPTVChannelFetcher(
00288 cardid, inputname, sourceid, scanMonitor);
00289
00290 MonitorProgress(false, false, false, false);
00291
00292 ok = freeboxScanner->Scan();
00293 #endif // USING_IPTV
00294
00295 if (!ok)
00296 InformUser(QObject::tr("Error starting scan"));
00297
00298 return ok;
00299 }
00300
00301 void ChannelScanner::PreScanCommon(
00302 int scantype,
00303 uint cardid,
00304 const QString &inputname,
00305 uint sourceid,
00306 bool do_ignore_signal_timeout,
00307 bool do_test_decryption)
00308 {
00309 uint signal_timeout = 1000;
00310 uint channel_timeout = 40000;
00311 CardUtil::GetTimeouts(cardid, signal_timeout, channel_timeout);
00312
00313 QString device = CardUtil::GetVideoDevice(cardid);
00314 if (device.isEmpty())
00315 {
00316 LOG(VB_GENERAL, LOG_ERR, LOC + "No Device");
00317 InformUser(QObject::tr("Programmer Error: No Device"));
00318 return;
00319 }
00320
00321 if (!scanMonitor)
00322 scanMonitor = new ScanMonitor(this);
00323
00324 QString card_type = CardUtil::GetRawCardType(cardid);
00325
00326 if ("DVB" == card_type)
00327 {
00328 QString sub_type = CardUtil::ProbeDVBType(device).toUpper();
00329 bool need_nit = (("QAM" == sub_type) ||
00330 ("QPSK" == sub_type) ||
00331 ("OFDM" == sub_type));
00332
00333
00334 if ((ScanTypeSetting::TransportScan == scantype) ||
00335 (ScanTypeSetting::FullTransportScan == scantype))
00336 {
00337 signal_timeout = (do_ignore_signal_timeout) ?
00338 channel_timeout * 10 : signal_timeout;
00339 }
00340
00341
00342 signal_timeout = max(signal_timeout, 1000U);
00343
00344
00345
00346
00347 channel_timeout = max(channel_timeout, need_nit * 7 * 1000U);
00348 }
00349
00350 #ifdef USING_DVB
00351 if ("DVB" == card_type)
00352 channel = new DVBChannel(device);
00353 #endif
00354
00355 #ifdef USING_V4L2
00356 if (("V4L" == card_type) || ("MPEG" == card_type))
00357 channel = new V4LChannel(NULL, device);
00358 #endif
00359
00360 #ifdef USING_HDHOMERUN
00361 if ("HDHOMERUN" == card_type)
00362 {
00363 channel = new HDHRChannel(NULL, device);
00364 }
00365 #endif // USING_HDHOMERUN
00366
00367 #ifdef USING_ASI
00368 if ("ASI" == card_type)
00369 {
00370 channel = new ASIChannel(NULL, device);
00371 }
00372 #endif // USING_ASI
00373
00374 if (!channel)
00375 {
00376 LOG(VB_GENERAL, LOG_ERR, LOC + "Channel not created");
00377 InformUser(QObject::tr("Programmer Error: Channel not created"));
00378 return;
00379 }
00380
00381
00382 channel->SetCardID(cardid);
00383
00384
00385 if (!channel->Open())
00386 {
00387 LOG(VB_GENERAL, LOG_ERR, LOC + "Channel could not be opened");
00388 InformUser(QObject::tr("Channel could not be opened."));
00389 return;
00390 }
00391
00392 ScanMonitor *lis = scanMonitor;
00393
00394 sigmonScanner = new ChannelScanSM(
00395 lis, card_type, channel, sourceid,
00396 signal_timeout, channel_timeout, inputname,
00397 do_test_decryption);
00398
00399
00400
00401
00402 switch (scantype)
00403 {
00404 case ScanTypeSetting::FullScan_ATSC:
00405 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeATSC);
00406 break;
00407 case ScanTypeSetting::FullScan_DVBC:
00408 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeDVBC);
00409 break;
00410 case ScanTypeSetting::FullScan_DVBT:
00411 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeDVBT);
00412 break;
00413 case ScanTypeSetting::NITAddScan_DVBT:
00414 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeDVBT);
00415 break;
00416 case ScanTypeSetting::NITAddScan_DVBS:
00417 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeDVBS1);
00418 break;
00419 case ScanTypeSetting::NITAddScan_DVBS2:
00420 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeDVBS2);
00421 break;
00422 case ScanTypeSetting::NITAddScan_DVBC:
00423 sigmonScanner->SetScanDTVTunerType(DTVTunerType::kTunerTypeDVBC);
00424 break;
00425 default:
00426 break;
00427 }
00428
00429
00430 SignalMonitor *mon = sigmonScanner->GetSignalMonitor();
00431 if (mon)
00432 mon->AddListener(lis);
00433
00434 DVBSignalMonitor *dvbm = NULL;
00435 bool using_rotor = false;
00436
00437 #ifdef USING_DVB
00438 dvbm = sigmonScanner->GetDVBSignalMonitor();
00439 if (dvbm && mon)
00440 using_rotor = mon->HasFlags(SignalMonitor::kDVBSigMon_WaitForPos);
00441 #endif // USING_DVB
00442
00443 MonitorProgress(mon, mon, dvbm, using_rotor);
00444 }