Ticket #1728: 02_one_active_eitscanner_per_backend.diff
File 02_one_active_eitscanner_per_backend.diff, 14.7 KB (added by , 18 years ago) |
---|
-
libs/libmythtv/tv_rec.cpp
=== libs/libmythtv/tv_rec.cpp ==================================================================
770 770 eitScanStartTime = QDateTime::currentDateTime(); 771 771 if ((internalState == kState_None) && (genOpt.cardtype == "DVB")) 772 772 { 773 // Add some randomness to avoid all cards starting 774 // EIT scanning at nearly the same time. 773 // start the eit scanning only if the encoder is idle_start sec idle 775 774 uint idle_start = gContext->GetNumSetting("EITCrawIdleStart", 60); 776 uint timeout = idle_start + (random() % 59); 777 eitScanStartTime = eitScanStartTime.addSecs(timeout); 775 eitScanStartTime = eitScanStartTime.addSecs(idle_start); 778 776 } 779 777 else 780 778 eitScanStartTime = eitScanStartTime.addYears(1); … … 1246 1244 SetFlags(kFlagRunMainLoop); 1247 1245 ClearFlags(kFlagExitPlayer | kFlagFinishRecording); 1248 1246 1249 // Add some randomness to avoid all cards starting 1250 // EIT scanning at nearly the same time. 1247 // start the eit scanning only if the encoder is idle_start sec idle 1251 1248 uint idle_start = gContext->GetNumSetting("EITCrawIdleStart", 60); 1252 uint timeout = idle_start + (random() % 59); 1253 eitScanStartTime = QDateTime::currentDateTime().addSecs(timeout); 1249 eitScanStartTime = QDateTime::currentDateTime().addSecs(idle_start); 1254 1250 1255 1251 while (HasFlags(kFlagRunMainLoop)) 1256 1252 { … … 3151 3147 VERBOSE(VB_RECORD, LOC + "SetChannel()" + " -- end"); 3152 3148 } 3153 3149 3150 /** \fn TVRec::StartEITScan(QString) 3151 * \brief Starts EIT scanning on the named channel and the current tuner. 3152 * 3153 * \param name channum of channel to scan on 3154 */ 3155 bool TVRec::StartEITScan(QString name) 3156 { 3157 // initialize eit scanner if needed 3158 if (!scanner && eitcache) 3159 scanner = new EITScanner(eitcache); 3160 3161 if (QDateTime::currentDateTime() > eitScanStartTime) 3162 { 3163 SetChannel(name, kFlagEITScan); 3164 uint ignore = gContext->GetNumSetting("EITIgnoresSource", 0); 3165 return true; 3166 } 3167 VERBOSE(VB_EIT, LOC + QString("Now: %1 - start scan only after: %2") 3168 .arg(QDateTime::currentDateTime().toString()) 3169 .arg(eitScanStartTime.toString())); 3170 3171 return false; 3172 } 3173 3154 3174 /** \fn TVRec::GetNextProgram(int,QString&,QString&,QString&,QString&,QString&,QString&,QString&,QString&,QString&,QString&,QString&,QString&) 3155 3175 * \brief Returns information about the program that would be seen if we changed 3156 3176 * the channel using ChangeChannel(int) with "direction". -
libs/libmythtv/tv_rec.h
=== libs/libmythtv/tv_rec.h ==================================================================
221 221 { SetChannel(QString("NextChannel %1").arg((int)dir)); } 222 222 void SetChannel(QString name, uint requestType = kFlagDetect); 223 223 224 bool StartEITScan(QString name); 225 224 226 int SetSignalMonitoringRate(int msec, int notifyFrontend = 1); 225 227 int ChangeColour(bool direction); 226 228 int ChangeContrast(bool direction); -
programs/mythbackend/encoderlink.h
=== programs/mythbackend/encoderlink.h ==================================================================
82 82 void ToggleChannelFavorite(void); 83 83 void ChangeChannel(int channeldirection); 84 84 void SetChannel(const QString &name); 85 bool StartEITScan(const QString chanid); 85 86 int ChangeContrast(bool direction); 86 87 int ChangeBrightness(bool direction); 87 88 int ChangeColour(bool direction); -
programs/mythbackend/mythbackend.pro
=== programs/mythbackend/mythbackend.pro ==================================================================
13 13 14 14 # Input 15 15 HEADERS += autoexpire.h encoderlink.h filetransfer.h httpstatus.h mainserver.h 16 HEADERS += playbacksock.h scheduler.h server.h housekeeper.h 16 HEADERS += playbacksock.h scheduler.h server.h housekeeper.h eitactivescanner.h 17 17 18 18 SOURCES += autoexpire.cpp encoderlink.cpp filetransfer.cpp httpstatus.cpp 19 19 SOURCES += main.cpp mainserver.cpp playbacksock.cpp scheduler.cpp server.cpp 20 SOURCES += housekeeper.cpp 20 SOURCES += housekeeper.cpp eitactivescanner.cpp 21 21 22 22 using_oss:DEFINES += USING_OSS 23 23 -
programs/mythbackend/main.cpp
=== programs/mythbackend/main.cpp ==================================================================
26 26 #include "encoderlink.h" 27 27 #include "remoteutil.h" 28 28 #include "housekeeper.h" 29 #include "eitactivescanner.h" 29 30 30 31 #include "libmyth/mythcontext.h" 31 32 #include "libmyth/mythdbcon.h" … … 42 43 QString lockfile_location; 43 44 HouseKeeper *housekeeping = NULL; 44 45 QString logfile = ""; 46 EITActiveScanner *eitscanner = NULL; 45 47 46 48 bool setupTVs(bool ismaster, bool &error) 47 49 { … … 595 597 else 596 598 jobqueue = new JobQueue(ismaster); 597 599 600 eitscanner = new EITActiveScanner(ismaster, &tvList); 598 601 VERBOSE(VB_IMPORTANT, QString("%1 version: %2 www.mythtv.org") 599 602 .arg(binname).arg(MYTH_BINARY_VERSION)); 600 603 -
programs/mythbackend/eitactivescanner.cpp
=== programs/mythbackend/eitactivescanner.cpp ==================================================================
1 // -*- Mode: c++ -*- 2 3 #include "eitactivescanner.h" 4 5 #include "libmythtv/tv_rec.h" 6 7 8 /***************************************************************************** 9 * 10 * Active EIT scanner: controls the TVRecs on the master backend 11 and holds a persistant event cache on each backend 12 */ 13 14 EITActiveScanner::EITActiveScanner(bool _ismaster, QMap<int, EncoderLink *> *tvList) 15 : exitThread(false), eitCache(new EITCache()), 16 cardList(tvList), ismaster(_ismaster) 17 { 18 pthread_create(&eventThread, NULL, SpawnEventLoop, this); 19 } 20 /* 21 void EITActiveScanner::TeardownAll(void) 22 { 23 StopActiveScan(); 24 if (!exitThread) 25 { 26 exitThread = true; 27 exitThreadCond.wakeAll(); 28 pthread_join(eventThread, NULL); 29 } 30 }*/ 31 32 /** \fn EITActiveScanner::SpawnEventLoop(void*) 33 * \brief Thunk that allows scanner_thread pthread to 34 * call EITActiveScanner::RunEventLoop(). 35 */ 36 void *EITActiveScanner::SpawnEventLoop(void *param) 37 { 38 EITActiveScanner *scanner = (EITActiveScanner*) param; 39 scanner->RunEventLoop(); 40 return NULL; 41 } 42 43 /** \fn EITActiveScanner::RunEventLoop() 44 * \brief This runs the event loop for EITActiveScanner until 'exitThread' is true. 45 */ 46 void EITActiveScanner::RunEventLoop(void) 47 { 48 exitThread = false; 49 50 // QMap<int, EncoderLink *>::iterator it = cardList->begin(); 51 // for (; it != cardList->end(); ++it) 52 // { 53 // TVRec *rec = it.data()->GetTVRec(); 54 // if (rec) 55 // { 56 // rec->SetEITCache(eitCache); 57 // } 58 // } 59 // if (ismaster) 60 StartActiveScan(); 61 62 63 64 while (!exitThread) 65 { 66 if (ismaster && (QDateTime::currentDateTime() > activeScanNextTrig) 67 && !cardList->isEmpty()) 68 { 69 // cerr << eitCache->GetStatistics() << endl; 70 if (activeScanNextCard == cardIDToSourceID.end()) 71 { 72 activeScanNextCard = cardIDToSourceID.begin(); 73 } 74 75 uint source = *activeScanNextCard; 76 77 int curCardID = activeScanNextCard.key(); 78 if (activeScanNextChan[source] == activeScanChannels[source].end()) 79 activeScanNextChan[source] = activeScanChannels[source].begin(); 80 81 if (!(*(activeScanNextChan[source])).isEmpty() && 82 (*cardList)[curCardID]->StartEITScan(*(activeScanNextChan[source]))) 83 { 84 VERBOSE(VB_GENERAL, QString("(%1)Now looking for EIT data on " 85 "multiplex of channel %2 of source %3") 86 .arg(curCardID).arg(*(activeScanNextChan[source])).arg(source)); 87 activeScanNextChan[source]++; 88 } 89 else 90 { 91 VERBOSE(VB_GENERAL, QString("Skipping card %1 in scan for EIT data on " 92 "multiplex of channel %2 of source %3") 93 .arg(curCardID).arg(*(activeScanNextChan[source])).arg(source)); 94 } 95 96 activeScanNextTrig = QDateTime::currentDateTime() 97 .addSecs(activeScanTrigTime); 98 99 activeScanNextCard++; 100 } 101 // TODO: prune old eit cache entries every now and then 102 103 exitThreadCond.wait(200); // sleep up to 200 ms. 104 } 105 } 106 107 void EITActiveScanner::StartActiveScan() 108 { 109 if (!activeScanSources.size()) 110 { 111 // get all source ids with useeit == 1 112 MSqlQuery query(MSqlQuery::InitCon()); 113 query.prepare( 114 "SELECT DISTINCT channel.sourceid " 115 "FROM channel, videosource " 116 "WHERE videosource.sourceid = channel.sourceid AND " 117 " channel.mplexid IS NOT NULL AND " 118 " useonairguide = 1 AND " 119 " useeit = 1 " 120 "GROUP BY mplexid " 121 "ORDER BY channel.sourceid, atscsrcid, mplexid"); 122 123 if (!query.exec() || !query.isActive()) 124 { 125 MythContext::DBError("EITActiveScanner::StartActiveScan", query); 126 return; 127 } 128 129 while (query.next()) 130 activeScanSources.push_back(query.value(0).toUInt()); 131 132 // getting mapping from cardid to sourceid with useeit == 1 133 query.prepare( 134 "SELECT cardid, videosource.sourceid " 135 "FROM videosource,cardinput " 136 "WHERE videosource.sourceid = cardinput.sourceid AND " 137 " useeit = 1 " 138 "ORDER BY cardid"); 139 140 if (!query.exec() || !query.isActive()) 141 { 142 MythContext::DBError("EITActiveScanner::StartActiveScan", query); 143 return; 144 } 145 146 while (query.next()) 147 cardIDToSourceID[query.value(0).toInt()] = query.value(1).toUInt(); 148 149 150 // get one channel with sourceid per mplexid 151 query.prepare( 152 "SELECT channel.sourceid, min(channum) " 153 "FROM channel, videosource " 154 "WHERE videosource.sourceid = channel.sourceid AND " 155 " channel.mplexid IS NOT NULL AND " 156 " useonairguide = 1 AND " 157 " useeit = 1 AND " 158 " channum != '' " 159 "GROUP BY mplexid " 160 "ORDER BY channel.sourceid, atscsrcid, mplexid"); 161 162 if (!query.exec() || !query.isActive()) 163 { 164 MythContext::DBError("EITScanner::StartActiveScan", query); 165 return; 166 } 167 168 while (query.next()) 169 { 170 VERBOSE(VB_EIT,QString("Adding channel %1 for source %2 to scan list") 171 .arg(query.value(0).toString()).arg(query.value(1).toUInt())); 172 activeScanChannels[query.value(0).toUInt()].push_back(query.value(1).toString()); 173 } 174 } 175 int number = 0; 176 for (vector<uint>::iterator it = activeScanSources.begin(); it != activeScanSources.end(); ++it) 177 { 178 activeScanNextChan[*it] = activeScanChannels[*it].begin(); 179 number += activeScanChannels[*it].size(); 180 } 181 182 VERBOSE(VB_EIT, 183 QString("StartActiveScan called with %1 multiplexes on %2 sources") 184 .arg(number).arg(activeScanSources.size())); 185 186 if (activeScanSources.size()) 187 { 188 uint max_seconds_per_source = gContext->GetNumSetting("EITTransportTimeout", 5) * 60; 189 190 activeScanNextTrig = QDateTime::currentDateTime(); 191 activeScanTrigTime = max_seconds_per_source / cardList->size(); 192 activeScanNextCard = cardIDToSourceID.begin(); 193 } 194 } -
programs/mythbackend/eitactivescanner.h
Property changes on: programs/mythbackend/eitactivescanner.cpp ___________________________________________________________________ Name: svn:mime-type +text/cpp === programs/mythbackend/eitactivescanner.h ==================================================================
1 // -*- Mode: c++ -*- 2 #ifndef EITACTIVESCANNER_H 3 #define EITACTIVESCANNER_H 4 5 // C includes 6 #include <pthread.h> 7 8 // Qt includes 9 #include <qobject.h> 10 #include <qdatetime.h> 11 #include <qstringlist.h> 12 #include <qwaitcondition.h> 13 14 // myth includes 15 #include "encoderlink.h" 16 17 #include "libmythtv/eitcache.h" 18 19 20 21 class EITActiveScanner 22 { 23 public: 24 EITActiveScanner(bool _ismaster, QMap<int, EncoderLink *> *tvList); 25 ~EITActiveScanner() {} 26 27 private: 28 void StartActiveScan(void); 29 void RunEventLoop(void); 30 static void *SpawnEventLoop(void*); 31 32 QMutex lock; 33 34 pthread_t eventThread; 35 bool exitThread; 36 QWaitCondition exitThreadCond; 37 38 EITCache *eitCache; 39 40 QDateTime activeScanNextTrig; 41 uint activeScanTrigTime; 42 43 vector<uint> activeScanSources; 44 QMap<uint, QStringList> activeScanChannels; 45 QMap<uint, QStringList::iterator> activeScanNextChan; 46 47 QMap<int, EncoderLink *> *cardList; 48 QMap<int, uint> cardIDToSourceID; 49 QMap<int, uint>::iterator activeScanNextCard; 50 51 bool ismaster; 52 }; 53 54 #endif //EITACTIVESCANNER_H -
programs/mythbackend/encoderlink.cpp
Property changes on: programs/mythbackend/eitactivescanner.h ___________________________________________________________________ Name: svn:mime-type +text/cpp === programs/mythbackend/encoderlink.cpp ==================================================================
199 199 return retval; 200 200 } 201 201 202 /** \fn EncoderLink::StartEITScan(const QString) 203 * \brief Tells TVRec to scan for EIT on channel chanid. 204 * \param chanid Channel to scan 205 */ 206 bool EncoderLink::StartEITScan(const QString chanid) 207 { 208 if (local) 209 return tv->StartEITScan(chanid); 210 else if (sock) 211 { 212 VERBOSE(VB_IMPORTANT, "StartEITScan is currently only supported locally"); 213 return false; 214 /*return sock->StartEITScan(m_capturecardnum, chanid);*/ 215 } 216 } 217 218 202 219 /** \fn EncoderLink::RecordPending(const ProgramInfo*, int) 203 220 * \brief Tells TVRec there is a pending recording "rec" in "secsleft" seconds. 204 221 * \param rec Recording to make.