diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am index 3c627b8d3..77823407f 100644 --- a/src/driver/Makefile.am +++ b/src/driver/Makefile.am @@ -32,6 +32,7 @@ libneutrino_driver_a_SOURCES = \ rcinput.cpp \ record.cpp \ ringbuffer.c \ + scanepg.cpp \ screen_max.cpp \ screenshot.cpp \ shutdown_count.cpp \ diff --git a/src/driver/scanepg.cpp b/src/driver/scanepg.cpp new file mode 100644 index 000000000..c53cc70c0 --- /dev/null +++ b/src/driver/scanepg.cpp @@ -0,0 +1,135 @@ +/* + Copyright (C) 2013 CoolStream International Ltd + + License: GPLv2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +extern CBouquetList * bouquetList; + +CEpgScan::CEpgScan() +{ + current_bnum = -1; +} + +CEpgScan::~CEpgScan() +{ +} + +CEpgScan * CEpgScan::getInstance() +{ + static CEpgScan * inst; + if (inst == NULL) + inst = new CEpgScan(); + return inst; +} + +void CEpgScan::Clear() +{ + scanmap.clear(); + current_bnum = -1; +} + +void CEpgScan::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data) +{ + if (!g_settings.epg_scan || CFEManager::getInstance()->getEnabledCount() <= 1) + return; + + if(msg == NeutrinoMessages::EVT_ZAP_COMPLETE) { + if(bouquetList->Bouquets.empty()) + return; + + if (current_bnum != bouquetList->getActiveBouquetNumber()) { + scanmap.clear(); + current_bnum = bouquetList->getActiveBouquetNumber(); + CChannelList * clist = bouquetList->Bouquets[current_bnum]->channelList; + int lsize = clist->Size(); + for (int i = 0; i < lsize; i++) { + CZapitChannel * chan = clist->getChannelFromIndex(i); + /* TODO: add interval check to clear scanned ? */ + if (scanned.find(chan->getTransponderId()) == scanned.end()) + scanmap.insert(eit_scanmap_pair_t(chan->getTransponderId(), chan->getChannelID())); + } + INFO("EVT_ZAP_COMPLETE, scan map size: %d\n", scanmap.size()); + } + } + else if (msg == NeutrinoMessages::EVT_EIT_COMPLETE) { + t_channel_id chid = *(t_channel_id *)data; + CZapitChannel * newchan = CServiceManager::getInstance()->FindChannel(chid); + if (newchan) { + scanned.insert(newchan->getTransponderId()); + scanmap.erase(newchan->getTransponderId()); + } + INFO("EIT read complete [" PRINTF_CHANNEL_ID_TYPE "], scan map size: %d", chid, scanmap.size()); + + if (scanmap.empty()) + return; + + t_channel_id live_channel_id = CZapit::getInstance()->GetCurrentChannelID(); + + CFrontend *live_fe = CZapit::getInstance()->GetLiveFrontend(); + CFEManager::getInstance()->lockFrontend(live_fe); +#ifdef ENABLE_PIP + CFrontend *pip_fe = CZapit::getInstance()->GetPipFrontend(); + if (pip_fe && pip_fe != live_fe) + CFEManager::getInstance()->lockFrontend(pip_fe); +#endif + for (eit_scanmap_iterator_t it = scanmap.begin(); it != scanmap.end(); /* ++it*/) { + CZapitChannel * newchan = CServiceManager::getInstance()->FindChannel(it->second); + if ((newchan == NULL) || SAME_TRANSPONDER(live_channel_id, newchan->getChannelID())) { + scanmap.erase(it++); + continue; + } + if (CFEManager::getInstance()->canTune(newchan)) { + INFO("try to scan [%s]", newchan->getName().c_str()); + bool ret = g_Zapit->zapTo_record(newchan->getChannelID()) > 0; + if (ret) { + g_Sectionsd->setServiceChanged(newchan->getChannelID(), false, newchan->getRecordDemux()); + break; + } else { + scanmap.erase(it++); + continue; + } + } else + INFO("skip [%s], cannot tune", newchan->getName().c_str()); + ++it; + } + CFEManager::getInstance()->unlockFrontend(live_fe); +#ifdef ENABLE_PIP + if (pip_fe && pip_fe != live_fe) + CFEManager::getInstance()->unlockFrontend(pip_fe); +#endif + } +} diff --git a/src/driver/scanepg.h b/src/driver/scanepg.h new file mode 100644 index 000000000..d3c74bc60 --- /dev/null +++ b/src/driver/scanepg.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2013 CoolStream International Ltd + + License: GPLv2 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SCAN_EPG__ +#define __SCAN_EPG__ + +#include + +typedef std::map eit_scanmap_t; +typedef std::pair eit_scanmap_pair_t; +typedef eit_scanmap_t::iterator eit_scanmap_iterator_t; + +class CEpgScan +{ + private: + int current_bnum; + eit_scanmap_t scanmap; + std::set scanned; + + CEpgScan(); + public: + ~CEpgScan(); + static CEpgScan * getInstance(); + + void handleMsg(const neutrino_msg_t _msg, neutrino_msg_data_t data); + void Clear(); +}; + +#endif