--- programs/mythcommflag/main.cpp.hibernate 2006-08-17 09:53:41.000000000 -0400 +++ programs/mythcommflag/main.cpp 2007-08-25 17:42:28.000000000 -0400 @@ -52,6 +52,13 @@ int jobID = -1; int lastCmd = -1; +JobMonitor *currentJobMonitor; + +static void rebuild_status_callback(int, void *) +{ + if (currentJobMonitor) + currentJobMonitor->hibernate(); +} int BuildVideoMarkup(QString& filename) { @@ -82,7 +89,7 @@ program_info); nvp->SetRingBuffer(tmprbuf); - nvp->RebuildSeekTable(!quiet); + nvp->RebuildSeekTable(!quiet, rebuild_status_callback); cerr << "Rebuilt\n"; @@ -255,7 +262,9 @@ if (jobID != -1) { - int curCmd = JobQueue::GetJobCmd(jobID); + int curCmd = currentJobMonitor ? currentJobMonitor->GetJobCmd() + : JobQueue::GetJobCmd(jobID); + if (curCmd == lastCmd) return; @@ -397,6 +406,10 @@ program_info->SetCommFlagged(COMM_FLAG_PROCESSING); + JobMonitor monitor(jobID); + + currentJobMonitor= jobID == -1 ? NULL: &monitor; + CustomEventRelayer cer(incomingCustomEvent); SlotRelayer a(commDetectorBreathe); SlotRelayer b(commDetectorStatusUpdate); @@ -447,7 +460,7 @@ } delete commDetector; - + currentJobMonitor=NULL; return comms_found; } @@ -537,7 +550,7 @@ if (rebuildSeekTable) { - nvp->RebuildSeekTable(); + nvp->RebuildSeekTable(false, rebuild_status_callback); if (!quiet) cerr << "Rebuilt\n"; --- programs/mythtranscode/transcode.cpp.hibernate 2006-08-23 18:20:59.000000000 -0400 +++ programs/mythtranscode/transcode.cpp 2007-08-25 17:42:28.000000000 -0400 @@ -609,6 +609,8 @@ QTime flagTime; flagTime.start(); + JobMonitor monitor(jobID); + while (nvp->TranscodeGetNextFrame(dm_iter, &did_ff, &is_key, honorCutList)) { if (first_loop) @@ -885,7 +887,7 @@ if ((jobID >= 0) || (print_verbose_messages & VB_IMPORTANT)) { - if (JobQueue::GetJobCmd(jobID) == JOB_STOP) + if (monitor.GetJobCmd() == JOB_STOP) { unlink(outputname); delete newFrame; --- programs/mythtranscode/mpeg2fix.cpp.hibernate 2006-10-03 14:17:33.000000000 -0400 +++ programs/mythtranscode/mpeg2fix.cpp 2007-08-25 17:42:28.000000000 -0400 @@ -14,6 +14,7 @@ #include #include #include +#include "jobqueue.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -199,8 +200,11 @@ MPEG2fixup::MPEG2fixup(const char *inf, const char *outf, QMap *deleteMap, const char *fmt, int norp, int fixPTS, int maxf, - bool showprog, int otype) + bool showprog, int otype, int jobIDarg) + : rx(jobID) { + jobID=jobIDarg; + displayFrame = new QPtrListIterator (vFrame); infile = inf; @@ -429,13 +433,14 @@ return (rx->WaitBuffers()); } -MPEG2replex::MPEG2replex() +MPEG2replex::MPEG2replex(int jobIDarg) { memset(&vrbuf, 0, sizeof(ringbuffer)); memset(&index_vrbuf, 0, sizeof(ringbuffer)); memset(&extrbuf, 0, sizeof(ringbuffer) * N_AUDIO); memset(&index_extrbuf, 0, sizeof(ringbuffer) * N_AUDIO); ext_count = 0; + jobID=jobIDarg; } MPEG2replex::~MPEG2replex() @@ -1804,8 +1809,12 @@ InitReplex(); + JobMonitor monitor(jobID); + while (1) { + monitor.hibernate(); + /* read packet */ if (! file_end) { @@ -2439,6 +2448,8 @@ AVPacket pkt; int count = 0; + JobMonitor monitor(jobID); + /*============ initialise AV ===============*/ if (!InitAV(file.ascii(), NULL, 0)) return TRANSCODE_EXIT_UNKNOWN_ERROR; @@ -2447,6 +2458,8 @@ while (av_read_frame(inputFC, &pkt) >= 0) { + monitor.hibernate(); + if (pkt.stream_index == vid_id) { if (pkt.flags & PKT_FLAG_KEY) --- programs/mythtranscode/mpeg2fix.h.hibernate 2006-02-18 13:44:52.000000000 -0500 +++ programs/mythtranscode/mpeg2fix.h 2007-08-25 17:42:28.000000000 -0400 @@ -102,7 +102,7 @@ class MPEG2replex { public: - MPEG2replex(); + MPEG2replex(int jobID); ~MPEG2replex(); void Start(); int WaitBuffers(); @@ -124,6 +124,7 @@ private: multiplex_t *mplex; + int jobID; }; class MPEG2fixup @@ -131,7 +132,8 @@ public: MPEG2fixup(const char *inf, const char *outf, QMap *deleteMap, const char *fmt, int norp, - int fixPTS, int maxf, bool showprog, int otype); + int fixPTS, int maxf, bool showprog, int otype, + int jobID); ~MPEG2fixup(); int Start(); void AddRangeList(QStringList cutlist, int type); @@ -224,6 +226,8 @@ QMap delMap; QMap saveMap; + int jobID; + pthread_t thread; AVFormatContext *inputFC; --- programs/mythtranscode/main.cpp.hibernate 2007-07-14 00:04:20.000000000 -0400 +++ programs/mythtranscode/main.cpp 2007-08-25 17:42:28.000000000 -0400 @@ -468,7 +468,7 @@ MPEG2fixup *m2f = new MPEG2fixup(infile.ascii(), outfile.ascii(), &deleteMap, NULL, false, false, 20, - showprogress, otype); + showprogress, otype, jobID); if (build_index) { int err = BuildKeyframeIndex(m2f, infile, posMap, jobID); --- programs/mythfilldatabase/filldata.cpp.hibernate 2007-08-25 16:20:59.000000000 -0400 +++ programs/mythfilldatabase/filldata.cpp 2007-08-25 18:29:28.000000000 -0400 @@ -46,6 +46,8 @@ #include "remoteutil.h" #include "videosource.h" // for is_grabber.. +#include "jobqueue.h" + using namespace std; static QString SetupIconCacheDirectory(); @@ -3942,7 +3944,10 @@ gContext->LogEntry("mythfilldatabase", LP_INFO, "Listings Download Started", ""); - + JobMonitor currentJob(-1); + + MSqlQuery::currentMonitor= ¤tJob; + if (!grab_data) { } --- libs/libmyth/mythdbcon.cpp.hibernate 2007-08-25 16:20:59.000000000 -0400 +++ libs/libmyth/mythdbcon.cpp 2007-08-25 17:56:25.000000000 -0400 @@ -6,6 +6,10 @@ #include #include +#include "../libmythtv/jobqueue.h" + +JobMonitor *MSqlQuery::currentMonitor=NULL; + MSqlDatabase::MSqlDatabase(const QString &name) { m_name = name; @@ -360,6 +364,14 @@ bool MSqlQuery::prepare(const QString& query) { + if (currentMonitor) + currentMonitor->hibernate(); + + return prepareNoCheck(query); +} + +bool MSqlQuery::prepareNoCheck(const QString& query) +{ static QMutex prepareLock; QMutexLocker lock(&prepareLock); return QSqlQuery::prepare(query); --- libs/libmyth/mythdbcon.h.hibernate 2006-04-03 04:58:08.000000000 -0400 +++ libs/libmyth/mythdbcon.h 2007-08-25 17:53:37.000000000 -0400 @@ -12,6 +12,8 @@ #include "mythcontext.h" +class JobMonitor; + /// \brief QSqlDatabase wrapper, used by MSqlQuery. Do not use directly. class MSqlDatabase { @@ -139,6 +141,12 @@ /// \brief Returns dedicated connection. (Required for using temporary SQL tables.) static MSqlQueryInfo DDCon(); + + + bool prepareNoCheck(const QString &query); + + static JobMonitor *currentMonitor; + private: MSqlDatabase *m_db; bool m_isConnected; --- libs/libmythtv/jobqueue.cpp.hibernate 2006-07-30 15:53:33.000000000 -0400 +++ libs/libmythtv/jobqueue.cpp 2007-08-25 17:57:23.000000000 -0400 @@ -26,6 +26,10 @@ #define LOC QString("JobQueue: ") #define LOC_ERR QString("JobQueue Error: ") +#include +#include +#include + JobQueue::JobQueue(bool master) { isMaster = master; @@ -972,8 +976,8 @@ MSqlQuery query(MSqlQuery::InitCon()); - query.prepare("UPDATE jobqueue SET comment = :COMMENT " - "WHERE id = :ID;"); + query.prepareNoCheck("UPDATE jobqueue SET comment = :COMMENT " + "WHERE id = :ID;"); query.bindValue(":COMMENT", comment); query.bindValue(":ID", jobID); @@ -2168,4 +2172,124 @@ return JOB_NONE; } +long JobMonitor::bogomips=0; + +/* +** Add up all bogomips in /proc/cpuinfo +*/ + +long JobMonitor::getEstimatedBogoMips() +{ + if (bogomips) + return bogomips; + + FILE *fp=fopen("/proc/cpuinfo", "r"); + char linebuf[256]; + + while (fp && fgets(linebuf, sizeof(linebuf), fp)) + { + char *p=strtok(linebuf, " \t:"); + + if (!p) + continue; + + if (strcmp(p, "bogomips") == 0) + { + p=strtok(NULL, " \t:"); + + if (p) + bogomips += atol(p); + } + } + if (fp) fclose(fp); + + return bogomips; +} + + + +JobMonitor::JobMonitor(int jobIDArg) + : jobID(jobIDArg), jobLastChk(time(NULL)), counter(1), + doMonitor(gContext->GetNumSetting("JobHibernate", -1)) +{ + if (doMonitor < 0) + doMonitor= getEstimatedBogoMips() < 3000; +} + +JobMonitor::~JobMonitor() +{ +} + +int JobMonitor::GetJobCmd() +{ + int jobCmd; + + while ((jobCmd=JobQueue::GetJobCmd(jobID)) == JOB_RUN) + { + if (!doHibernateCheck()) + break; + } + + return jobCmd; +} + +void JobMonitor::hibernate() +{ + while (doHibernateCheck()) + ; +} + +bool JobMonitor::doHibernateCheck() +{ + if (!doMonitor) + return false; + + time_t t=time(NULL); + + if (t == jobLastChk) + return false; + + if (t < jobLastChk) + counter=0; // Time went backwards? + else if (t - jobLastChk > counter) + counter=0; + else + counter -= t - jobLastChk; + + jobLastChk=t; + + if (counter) + return false; + + counter=5; + + bool isActive=false; + + MSqlQuery query(MSqlQuery::InitCon()); + query.prepareNoCheck("SELECT recusage FROM inuseprograms"); + if (query.exec() && query.isActive() && query.size() > 0) + while (query.next()) + { + QString usage= + query.value(0).toString().lower(); + + if (usage == "player" || + usage == "recorder" || + usage.left(7) == "preview") + isActive=true; + } + + if (!isActive) + return false; + counter=1; + if (jobID >= 0 && + !JobQueue::ChangeJobComment(jobID, + "waiting for record/playback to stop")) + { + return false; + } + sleep(5); + return true; +} + /* vim: set expandtab tabstop=4 shiftwidth=4: */ --- libs/libmythtv/jobqueue.h.hibernate 2006-07-15 16:13:46.000000000 -0400 +++ libs/libmythtv/jobqueue.h 2007-08-25 17:42:28.000000000 -0400 @@ -219,6 +219,30 @@ QMutex queueThreadCondLock; }; +#include + +class JobMonitor { + int jobID; + time_t jobLastChk; + int counter; + + int doMonitor; + + static long bogomips; + + public: + JobMonitor(int jobID); + virtual ~JobMonitor(); + + int GetJobCmd(); + virtual void hibernate(); + + static long getEstimatedBogoMips(); + + private: + bool doHibernateCheck(); +}; + #endif /* vim: set expandtab tabstop=4 shiftwidth=4: */