Index: libs/libmythtv/tv_rec.h
===================================================================
--- libs/libmythtv/tv_rec.h	(revision 17451)
+++ libs/libmythtv/tv_rec.h	(working copy)
@@ -371,6 +371,9 @@
     TuningQueue    tuningRequests;
     TuningRequest  lastTuningRequest;
     QDateTime      eitScanStartTime;
+    QDateTime      eitScanStopTime;
+    uint           activeScanCycleTime;
+    uint           activeScanDuration;
     QWaitCondition triggerEventLoop;
     QWaitCondition triggerEventSleep;
     bool           m_switchingBuffer;
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 17451)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -890,6 +890,7 @@
     // to avoid race condition with it's tuning requests.
     if (HasFlags(kFlagEITScannerRunning))
     {
+        VERBOSE(VB_EIT, LOC + "Stopping EIT Active Scan due to tuning.");
         scanner->StopActiveScan();
         ClearFlags(kFlagEITScannerRunning);
     }
@@ -1309,6 +1310,15 @@
     SetFlags(kFlagRunMainLoop);
     ClearFlags(kFlagExitPlayer | kFlagFinishRecording);
 
+    uint activeCycleSleepSecs;
+    uint activeScanNumMuxes;
+    QStringList LocalactiveScanChannels;
+
+    bool ScanStopped;
+
+    ScanStopped = true;
+    activeScanNumMuxes = 0;
+
     eitScanStartTime = QDateTime::currentDateTime();    
     // check whether we should use the EITScanner in this TVRec instance
     if (CardUtil::IsEITCapable(genOpt.cardtype) &&
@@ -1444,6 +1454,8 @@
             ClearFlags(kFlagExitPlayer);
         }
 
+
+	// EIT Scanner handling
         if (channel && scanner &&
             QDateTime::currentDateTime() > eitScanStartTime)
         {
@@ -1458,15 +1470,119 @@
                         "for all sources on this card.");
                 eitScanStartTime = eitScanStartTime.addYears(1);
             }
+            // Things are good to start Active Scan
+            // We now know that currentDateTime > eitScanStartTime but we don't know if
+	    // we have exceeded the eitScanStopTime
             else
             {
+		// We only query the database once, when we start
+                if (!activeScanNumMuxes)
+                {
+		    // Obtain the number of multiplexes by database query 
+        	    MSqlQuery query(MSqlQuery::InitCon());
+        	    query.prepare(
+            	    "SELECT channum, MIN(chanid) "
+            	    "FROM channel, cardinput, capturecard, videosource "
+            	    "WHERE cardinput.sourceid   = channel.sourceid AND "
+            	    "      videosource.sourceid = channel.sourceid AND "
+            	    "      capturecard.cardid   = cardinput.cardid AND "
+            	    "      channel.mplexid        IS NOT NULL      AND "
+            	    "      useonairguide        = 1                AND "
+            	    "      useeit               = 1                AND "
+            	    "      channum             != ''               AND "
+            	    "      cardinput.cardid     = :CARDID "
+            	    "GROUP BY mplexid "
+            	    "ORDER BY cardinput.sourceid, mplexid, "
+            	    "         atsc_major_chan, atsc_minor_chan ");
+        	    query.bindValue(":CARDID", GetCaptureCardNum());
+    
+        	    if (!query.exec() || !query.isActive())
+        	    {
+            	    MythContext::DBError("TVRec::StartActiveScan", query);
+                    VERBOSE(VB_EIT, LOC + "Database query for number of multiplexes failed - assuming 1.");
+        	    activeScanNumMuxes = 1;
+        	    }
+		    else 
+		    {
+                        while (query.next())
+            	        LocalactiveScanChannels.push_back(query.value(0).toString());
+    
+        	        activeScanNumMuxes = LocalactiveScanChannels.size();
+        
+        	        VERBOSE(VB_EIT, LOC +
+            	        QString("Database query returns %1 DVB multiplexes.")
+            	           .arg(activeScanNumMuxes));
+		    }
+                }
+
+		// Following are control variables for the improved active scan
+		// It stops after a defined period and closes the tuner card,
+		// the idea is to see if it saves some power. There is usually no need
+		// to scan for EIT data continuously.
+	
+		// Set the repeat rate of the active scan to 60 minutes
+        	activeScanCycleTime = 60;
+		// It would be wise to schedule an EIT scan shortly before a recording,
+		// to check for re-schedules.
+	
+		// Set the duration of the active scan to 2 minutes per mux per hour
+		// Configuration Note:
+		// If using less than 5 minutes per mux, set "EIT Transport Timeout"
+		// in mythv-setup to a figure which ensures all muxes will be read,
+		// i.e. equal to or less than 2 minutes.
+        	activeScanDuration = activeScanNumMuxes * 2 * 60;
+	
+        	eitScanStopTime = eitScanStartTime
+                    	.addSecs(activeScanDuration);
+	
+		// Log some information about the settings
+        	VERBOSE(VB_EIT, LOC +
+            	QString("Improved Active Scan cycle time %1 minutes")
+            	.arg(activeScanCycleTime));
+        	VERBOSE(VB_EIT, LOC +
+            	QString("Improved Active Scan Duration   %1 minutes")
+            	.arg(activeScanDuration/60));
+	
+	        ScanStopped = false ; 
+
+		// Active Scan is restarted after a recording uses the tuner, so the
+		// relative position of the 'window' moves as recordings are made.
+		// If settings give poor programme guide population, they can be changed
+		// Ideally there could be a control in mythtv-setup where active scan is enabled
+
+                VERBOSE(VB_EIT, LOC + "EIT Active Scan being (re)started.");
                 scanner->StartActiveScan(
                     this, eitTransportTimeout, eitIgnoresSource);
                 SetFlags(kFlagEITScannerRunning);
+		// This next line prevents multiple entries into this 'if' if scan has started
                 eitScanStartTime = QDateTime::currentDateTime().addYears(1);
             }
         }
+	else if (channel && scanner && 
+	    (QDateTime::currentDateTime() > eitScanStopTime) && !ScanStopped )
+        {
+	    // Now we catch the same conditions but with eitScanStopTime exceeded
+	    // and we haven't already been here, ie. ScanStopped is still false
 
+            VERBOSE(VB_EIT, LOC + "Reached Active Scan Duration, ceasing active scan until next cycle. Flushing cache...");
+	    scanner->StopActiveScan();
+	    ScanStopped = true ; 
+            CloseChannel(); 
+
+            // Now calculate the number of seconds we have to wait to complete the
+            // Active Scan Cycle. This way, the cycle will always be same length.
+	    // (Apart from recordings which will extend the cycle)
+            // activeScanCycleTime is in minutes and activeScanDuration is in secs
+            activeCycleSleepSecs = activeScanCycleTime * 60 - activeScanDuration;
+            VERBOSE(VB_EIT, LOC +
+                QString("Calculated Active Scan wait time of %1 minutes. Active Scan will resume then.")
+                   .arg(activeCycleSleepSecs/60));
+
+	    // We have to wait for activeCycleSleepSecs. This is easily achieved
+	    // by doing nothing until the appropriate time is reached
+            eitScanStartTime = QDateTime::currentDateTime().addSecs(activeCycleSleepSecs);
+        }
+
         // We should be no more than a few thousand milliseconds,
         // as the end recording code does not have a trigger...
         // NOTE: If you change anything here, make sure that
