--- 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 <netinet/in.h>
 #include <getopt.h>
 #include <stdint.h>
+#include "jobqueue.h"
 
 #ifndef O_LARGEFILE
 #define O_LARGEFILE 0
@@ -199,8 +200,11 @@
 MPEG2fixup::MPEG2fixup(const char *inf, const char *outf,
                        QMap<long long, int> *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<MPEG2frame> (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<long long, int> *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<long long, int> delMap;
     QMap<long long, int> 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= &currentJob;
+
     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 <qregexp.h>
 #include <qvaluevector.h>
 
+#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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
 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 <time.h>
+
+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: */
