Index: mythtv/libs/libmythtv/tv_rec.h
===================================================================
--- mythtv.orig/libs/libmythtv/tv_rec.h	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/tv_rec.h	2006-05-21 14:47:33.000000000 +1000
@@ -169,13 +169,13 @@
     void RecordPending(const ProgramInfo *rcinfo, int secsleft);
     RecStatusType StartRecording(const ProgramInfo *rcinfo);
 
-    void StopRecording(void);
+    void StopRecording(ProgramInfo *rec);
     /// \brief Tells TVRec to finish the current recording as soon as possible.
     void FinishRecording(void)  { SetFlags(kFlagFinishRecording); }
     /// \brief Tells TVRec that the frontend's TV class is ready for messages.
     void FrontendReady(void)    { SetFlags(kFlagFrontendReady); }
     void CancelNextRecording(bool cancel);
-    ProgramInfo *GetRecording(void);
+    ProgramList GetRecordings(void);
 
     /// \brief Returns true if event loop has not been told to shut down
     bool IsRunning(void)  const { return HasFlags(kFlagRunMainLoop); }
@@ -337,9 +337,11 @@
 
     void SetOption(RecordingProfile &profile, const QString &name);
 
+    void DoneAddingRecording();
+
     // Various components TVRec coordinates
     RecorderMuxBase  *recorderMux;
-    RecorderBase     *recorder;
+    QMap<ProgramInfo *, RecorderBase *>  recorders;
     ChannelBase      *channel;
     SignalMonitor    *signalMonitor;
     EITScanner       *scanner;
@@ -383,6 +385,12 @@
     QWaitCondition triggerEventLoop;
     QWaitCondition triggerEventSleep;
 
+    // Current recording info SPLIT
+    ProgramList   curRecordings;
+    ProgramInfo  *newRecording;
+    RecorderBase *newRecorder;
+    QMutex        newRecordingLock;
+
     // Current recording info
     ProgramInfo *curRecording;
     QDateTime    recordEndTime;
@@ -399,6 +407,10 @@
     // LiveTV file chain
     LiveTVChain *tvchain;
 
+    // RingBuffer info SPLIT
+    RingBuffer *newRingBuffer;
+    QMap<ProgramInfo *, RingBuffer *> ringBuffers;
+
     // RingBuffer info
     RingBuffer  *ringBuffer;
     QString      rbFilePrefix;
Index: mythtv/libs/libmythtv/tv_rec.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/tv_rec.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/tv_rec.cpp	2006-05-21 14:49:00.000000000 +1000
@@ -94,6 +94,32 @@
 static bool is_dishnet_eit(int cardid);
 static QString load_profile(QString,void*,ProgramInfo*,RecordingProfile&);
 
+static int comp_recend(ProgramInfo *a, ProgramInfo *b)
+{
+    if (a->recendts != b->recendts)
+    {
+        if (a->recendts > b->recendts)
+            return 1;
+        else
+            return -1;
+    }
+    if (a->recstartts != b->recstartts)
+    {
+        if (a->recstartts > b->recstartts)
+            return 1;
+        else
+            return -1;
+    }
+    if (a->chansign != b->chansign)
+    {
+        if (a->chansign < b->chansign)
+            return 1;
+        else
+            return -1;
+    }
+    return 0;
+}
+
 /** \class TVRec
  *  \brief This is the coordinating class of the \ref recorder_subsystem.
  *
@@ -120,7 +146,7 @@
  */
 TVRec::TVRec(int capturecardnum)
        // Various components TVRec coordinates
-    : recorderMux(NULL), recorder(NULL), channel(NULL), signalMonitor(NULL),
+    : recorderMux(NULL), channel(NULL), signalMonitor(NULL),
       scanner(NULL), dvbsiparser(NULL),
       // Configuration variables from database
       transcodeFirst(false), earlyCommFlag(false), runJobOnHostOnly(false),
@@ -133,6 +159,8 @@
       internalState(kState_None), desiredNextState(kState_None),
       changeState(false), pauseNotify(true),
       stateFlags(0), lastTuningRequest(0),
+      // Current recording info SPLIT
+      curRecordings(false), newRecording(NULL), newRecorder(NULL),
       // Current recording info
       curRecording(NULL), autoRunJobs(JOB_NONE),
       // Pending recording info
@@ -141,6 +169,8 @@
       pseudoLiveTVRecording(NULL),
       // tvchain
       tvchain(NULL),
+      // RingBuffer info SPLIT
+      newRingBuffer(NULL),
       // RingBuffer info
       ringBuffer(NULL), rbFilePrefix(""), rbFileExt("mpg")
 {
@@ -330,29 +360,33 @@
     return internalState;
 }
 
-/** \fn TVRec::GetRecording(void)
- *  \brief Allocates and returns a ProgramInfo for the current recording.
+/** \fn TVRec::GetRecordings(void)
+ *  \brief Allocates and returns a ProgramList for the current recordings.
  *
- *  Note: The user of this function must free the %ProgramInfo this returns.
- *  \return %ProgramInfo for the current recording, if it exists, blank
- *          %ProgramInfo otherwise.
+ *  Note: The user of this function must free the %ProgramInfo objects
+ *  this returns.
+ *  \return %ProgramList for the current recordings, an empty list is
+ *          returned if there are no current recordings.
  */
-ProgramInfo *TVRec::GetRecording(void)
+ProgramList TVRec::GetRecordings(void)
 {
     QMutexLocker lock(&stateChangeLock);
 
-    ProgramInfo *tmppginfo = NULL;
+    ProgramList retlist(false);
+
+    if (changeState)
+        return retlist;
 
-    if (curRecording && !changeState)
+    for (ProgramInfo *rec = curRecordings.first();
+         rec; rec = curRecordings.next())
     {
-        tmppginfo = new ProgramInfo(*curRecording);
+        ProgramInfo *tmppginfo = new ProgramInfo(*rec);
         tmppginfo->recstatus = rsRecording;
+        tmppginfo->cardid = cardid;
+        retlist.append(tmppginfo);
     }
-    else
-        tmppginfo = new ProgramInfo();
-    tmppginfo->cardid = cardid;
 
-    return tmppginfo;
+    return retlist;
 }
 
 /** \fn TVRec::RecordPending(const ProgramInfo*, int)
@@ -419,7 +453,7 @@
  *  \return +1 if the recording started successfully,
  *          -1 if TVRec is busy doing something else, 0 otherwise.
  *  \sa EncoderLink::StartRecording(const ProgramInfo*)
- *      RecordPending(const ProgramInfo*, int), StopRecording()
+ *      RecordPending(const ProgramInfo*, int), StopRecording(ProgramInfo *rec)
  */
 RecStatusType TVRec::StartRecording(const ProgramInfo *rcinfo)
 {
@@ -435,8 +469,13 @@
 
     // We need to do this check early so we don't cancel an overrecord
     // that we're trying to extend.
-    if (internalState != kState_WatchingLiveTV && 
-        curRecording &&
+    if (internalState != kState_WatchingLiveTV)
+    {
+        // change this to rec later
+        for (ProgramInfo *curRecording = curRecordings.first(); curRecording;
+             curRecording = curRecordings.next())
+        {
+            if (curRecording &&
         curRecording->title == rcinfo->title &&
         curRecording->chanid == rcinfo->chanid &&
         curRecording->startts == rcinfo->startts)
@@ -449,7 +488,10 @@
         MythEvent me("RECORDING_LIST_CHANGE");
         gContext->dispatch(me);
 
-        recordEndTime = curRecording->recendts.addSecs(post_roll_seconds);
+                // Resort the list of current recordings so that the recording
+                // that will end first is at the front of the list
+                curRecordings.Sort(comp_recend);
+                recordEndTime = curRecordings.getFirst()->recendts.addSecs(post_roll_seconds);
 
         msg = QString("updating recording: %1 %2 %3 %4")
             .arg(curRecording->title).arg(curRecording->chanid)
@@ -461,6 +503,8 @@
 
         retval = rsRecording;
         return retval;
+            }
+        }
     }
 
     if (pendingRecording)
@@ -474,7 +518,9 @@
     // Flush out events...
     WaitForEventThreadSleep();
 
+    // SPLIT how does this test if recording is in post-roll?
     // If in post-roll, end recording
+#if 0
     if (GetState() == kState_RecordingOnly &&
         !HasFlags(kFlagCancelNextRecording))
     {
@@ -482,6 +528,7 @@
         StopRecording();
         stateChangeLock.lock();
     }
+#endif
 
     if (internalState == kState_None)
     {
@@ -493,12 +540,11 @@
             tvchain = NULL;
         }
 
-        recordEndTime = GetRecordEndTime(rcinfo);
-
         // Tell event loop to begin recording.
-        curRecording = new ProgramInfo(*rcinfo);
-        curRecording->MarkAsInUse(true, "recorder");
-        StartedRecording(curRecording);
+        newRecordingLock.lock();
+        newRecording = new ProgramInfo(*rcinfo);
+        newRecording->MarkAsInUse(true, "recorder");
+        StartedRecording(newRecording);
 
         // Make sure scheduler is allowed to end this recording
         ClearFlags(kFlagCancelNextRecording);
@@ -524,6 +570,16 @@
 
         retval = rsRecording;
     }
+    else if (!HasFlags(kFlagCancelNextRecording) && true /* OnSameMux (this should be true if the scheduler is working right)*/)
+    {
+        // Haven't integrated with LiveTV yet
+        newRecordingLock.lock();
+        newRecording = new ProgramInfo(*rcinfo);
+        newRecording->MarkAsInUse(true, "recorder");
+        StartedRecording(newRecording);
+
+        retval = rsRecording;
+    }
     else if (!HasFlags(kFlagCancelNextRecording))
     {
         msg = QString("Wanted to record: %1 %2 %3 %4\n"
@@ -532,11 +588,18 @@
               .arg(rcinfo->recstartts.toString())
               .arg(rcinfo->recendts.toString())
               .arg(StateToString(internalState));
-        if (curRecording && internalState == kState_RecordingOnly)
+        if (!curRecordings.isEmpty() && internalState == kState_RecordingOnly)
+        {
+            // Change this to rec later
+            for (ProgramInfo *curRecording = curRecordings.first();
+                 curRecording; curRecording = curRecordings.next())
+            {
             msg += QString("\n\t\t\tCurrently recording: %1 %2 %3 %4")
                 .arg(curRecording->title).arg(curRecording->chanid)
                 .arg(curRecording->recstartts.toString())
                 .arg(curRecording->recendts.toString());
+            }
+        }
         VERBOSE(VB_IMPORTANT, LOC + msg);
 
         retval = rsTunerBusy;
@@ -547,13 +610,23 @@
     return retval;
 }
 
-/** \fn TVRec::StopRecording(void)
+/** \fn TVRec::StopRecording(ProgramInfo *rec)
  *  \brief Changes from kState_RecordingOnly to kState_None.
  *  \sa StartRecording(const ProgramInfo *rec), FinishRecording()
  */
-void TVRec::StopRecording(void)
+void TVRec::StopRecording(ProgramInfo *rec)
 {
-    if (StateIsRecording(GetState()))
+    if (curRecordings.contains(rec))
+    {
+        recorders[rec]->StopRecording();
+        FinishedRecording(rec);
+        curRecordings.remove(rec);
+
+        if (!curRecordings.isEmpty())
+            recordEndTime = GetRecordEndTime(curRecordings.getFirst());
+    }
+
+    if (curRecordings.isEmpty() && StateIsRecording(GetState()))
     {
         QMutexLocker lock(&stateChangeLock);
         ChangeState(RemoveRecording(GetState()));
@@ -750,7 +823,7 @@
     else if (TRANSITION(kState_None, kState_RecordingOnly))
     {
         SetPseudoLiveTVRecording(NULL);
-        tuningRequests.enqueue(TuningRequest(kFlagRecording, curRecording));
+        tuningRequests.enqueue(TuningRequest(kFlagRecording, newRecording));
         SET_NEXT();
     }
     else if (TRANSITION(kState_RecordingOnly, kState_None))
@@ -805,7 +878,7 @@
 void TVRec::SetOption(RecordingProfile &profile, const QString &name)
 {
     int value = profile.byName(name)->getValue().toInt();
-    recorder->SetOption(name, value);
+    newRecorder->SetOption(name, value);
 }
 
 /** \fn TVRec::SetupRecorderMux(RecordingProfile&)
@@ -943,7 +1016,7 @@
  */
 bool TVRec::SetupNewRecorder(RecordingProfile &profile)
 {
-    recorder = recorderMux->CreateNewRecorder(this);
+    newRecorder = recorderMux->CreateNewRecorder(this);
     if (genOpt.cardtype == "MPEG")
     {
 #ifdef USING_IVTV
@@ -954,8 +1027,8 @@
     {
 #ifdef USING_V4L
         VERBOSE(VB_RECORD, LOC + QString("Creating new HDTVRecorder"));
-        ringBuffer->SetWriteBufferSize(4*1024*1024);
-        recorder->SetOption("wait_for_seqstart", genOpt.wait_for_seqstart);
+        newRingBuffer->SetWriteBufferSize(4*1024*1024);
+        newRecorder->SetOption("wait_for_seqstart", genOpt.wait_for_seqstart);
 #endif // USING_V4L
     }
     else if (genOpt.cardtype == "FIREWIRE")
@@ -965,11 +1038,11 @@
         VERBOSE(VB_RECORD, LOC + QString("Creating new DarwinFirewireRecorder"));
 # else 
         VERBOSE(VB_RECORD, LOC + QString("Creating new FirewireRecorder"));
-        recorder->SetOption("port",       fwOpt.port);
-        recorder->SetOption("node",       fwOpt.node);
-        recorder->SetOption("speed",      fwOpt.speed);
-        recorder->SetOption("model",      fwOpt.model);
-        recorder->SetOption("connection", fwOpt.connection);
+        newRecorder->SetOption("port",       fwOpt.port);
+        newRecorder->SetOption("node",       fwOpt.node);
+        newRecorder->SetOption("speed",      fwOpt.speed);
+        newRecorder->SetOption("model",      fwOpt.model);
+        newRecorder->SetOption("connection", fwOpt.connection);
 # endif // !CONFIG_DARWIN 
 #endif // USING_FIREWIRE
     }
@@ -977,26 +1050,26 @@
     {
 #ifdef USING_DBOX2
         VERBOSE(VB_RECORD, LOC + QString("Creating new DBox2Recorder"));
-        recorder->SetOption("port",     dboxOpt.port);
-        recorder->SetOption("host",     dboxOpt.host);
-        recorder->SetOption("httpport", dboxOpt.httpport);
+        newRecorder->SetOption("port",     dboxOpt.port);
+        newRecorder->SetOption("host",     dboxOpt.host);
+        newRecorder->SetOption("httpport", dboxOpt.httpport);
 #endif // USING_DBOX2
     }
     else if (genOpt.cardtype == "HDHOMERUN")
     {
 #ifdef USING_HDHOMERUN
         VERBOSE(VB_RECORD, LOC + QString("Creating new HDHRRecorder"));
-        ringBuffer->SetWriteBufferSize(4*1024*1024);
-        recorder->SetOption("wait_for_seqstart", genOpt.wait_for_seqstart);
+        newRingBuffer->SetWriteBufferSize(4*1024*1024);
+        newRecorder->SetOption("wait_for_seqstart", genOpt.wait_for_seqstart);
 #endif // USING_HDHOMERUN
     }
     else if (genOpt.cardtype == "DVB")
     {
 #ifdef USING_DVB
         VERBOSE(VB_RECORD, LOC + QString("Creating new DVBRecorder"));
-        ringBuffer->SetWriteBufferSize(4*1024*1024);
-        recorder->SetOption("wait_for_seqstart", genOpt.wait_for_seqstart);
-        recorder->SetOption("dvb_on_demand",     dvbOpt.dvb_on_demand);
+        newRingBuffer->SetWriteBufferSize(4*1024*1024);
+        newRecorder->SetOption("wait_for_seqstart", genOpt.wait_for_seqstart);
+        newRecorder->SetOption("dvb_on_demand",     dvbOpt.dvb_on_demand);
 #endif // USING_DVB
     }
     else
@@ -1004,16 +1077,16 @@
 #ifdef USING_V4L
         // V4L/MJPEG/GO7007 from here on
         VERBOSE(VB_RECORD, LOC + QString("Creating new NuppelVideoRecorder"));
-        recorder->SetOption("skipbtaudio", genOpt.skip_btaudio);
+        newRecorder->SetOption("skipbtaudio", genOpt.skip_btaudio);
 #endif // USING_V4L
     }
 
-    if (recorder)
+    if (newRecorder)
     {
-        recorder->SetOptionsFromProfile(
+        newRecorder->SetOptionsFromProfile(
             &profile, genOpt.videodev, genOpt.audiodev, genOpt.vbidev);
-        recorder->SetRingBuffer(ringBuffer);
-        recorder->Initialize();
+        newRecorder->SetRingBuffer(newRingBuffer);
+        newRecorder->Initialize();
 
         return true;
     }
@@ -1052,6 +1125,12 @@
 
     VERBOSE(VB_RECORD, LOC + "TeardownRecorder - Start");
 
+    // SPLIT This should shutdown each recorder
+    if (!recorders.isEmpty())
+    {
+        VERBOSE(VB_RECORD, LOC + "There are still recorders attached to mux");
+    }
+
     if (recorderMux && HasFlags(kFlagRecorderRunning))
     {
         // This is a bad way to calculate this, the framerate
@@ -1083,13 +1162,14 @@
 
         delete recorderMux;
         recorderMux = NULL;
-        delete recorder;
-        recorder = NULL;
     }
 
+    // SPLIT this should be deleted
     if (ringBuffer)
         ringBuffer->StopReads();
 
+    // SPLIT this should be deleted, or atleast move to where each recording
+    // is stoped
     if (curRecording)
     {
         if (!killFile)
@@ -1155,7 +1235,7 @@
 DVBRecorder *TVRec::GetDVBRecorder(void)
 {
 #ifdef USING_DVB
-    return dynamic_cast<DVBRecorder*>(recorder);
+    return dynamic_cast<DVBRecorder*>(newRecorder);
 #else // if !USING_DVB
     return NULL;
 #endif // !USING_DVB
@@ -1164,7 +1244,7 @@
 HDTVRecorder *TVRec::GetHDTVRecorder(void)
 {
 #ifdef USING_V4L
-    return dynamic_cast<HDTVRecorder*>(recorder);
+    return dynamic_cast<HDTVRecorder*>(newRecorder);
 #else // if !USING_V4L
     return NULL;
 #endif // USING_V4L
@@ -1173,7 +1253,7 @@
 HDHRRecorder *TVRec::GetHDHRRecorder(void)
 {
 #ifdef USING_HDHOMERUN
-    return dynamic_cast<HDHRRecorder*>(recorder);
+    return dynamic_cast<HDHRRecorder*>(newRecorder);
 #else // if !USING_HDHOMERUN
     return NULL;
 #endif // !USING_HDHOMERUN
@@ -1388,9 +1468,13 @@
 
     while (HasFlags(kFlagRunMainLoop))
     {
+        if (newRecording)
+            VERBOSE(VB_RECORD, LOC + QString("Noticed newRecording(%1)").arg(newRecording->title));
+
         // If there is a state change queued up, do it...
         if (changeState)
         {
+            VERBOSE(VB_RECORD, LOC + "SPLIT: changeState");
             HandleStateChange();
             ClearFlags(kFlagFrontendReady | kFlagCancelNextRecording);
             SetFlags(kFlagAskAllowRecording);
@@ -1408,10 +1492,33 @@
         // Handle any tuning events..
         HandleTuning();
 
+        // SPLIT
+        // Additional new recordings on the same mux are added here
+        // Setup the recorder
+        if (recorderMux && newRecording)
+        {
+            VERBOSE(VB_RECORD, LOC + "Adding additional recorders");
+
+            RecordingProfile profile;
+            QString profileName = load_profile(genOpt.cardtype, NULL, newRecording, profile);
+
+            SetRingBuffer(new RingBuffer(newRecording->GetFileName(), true));
+
+            if (!SetupNewRecorder(profile))
+                VERBOSE(VB_RECORD, LOC_ERR + "Failed to add an additional recorder!");
+
+            newRecorder->SetRecording(newRecording);
+
+            DoneAddingRecording();
+        }
+        // End add additional new recordings on the same mux
+        // new recordings should be added to the list by now
+
         // If we have a pending recording and AskAllowRecording is set
         // and the frontend is ready send an ASK_RECORDING query to frontend.
         if (pendingRecording && HasFlags(kFlagAskAllowRecording))
         {
+            VERBOSE(VB_RECORD, LOC + "SPLIT: Ask Allow Recording");
             ClearFlags(kFlagAskAllowRecording);
 
             if (GetState() == kState_WatchingLiveTV)
@@ -1441,20 +1548,27 @@
 
         // If we are recording a program, check if the recording is
         // over or someone has asked us to finish the recording.
-        if (GetState() == kState_RecordingOnly &&
+        if (recorderMux && GetState() == kState_RecordingOnly &&
             (QDateTime::currentDateTime() > recordEndTime ||
              HasFlags(kFlagFinishRecording)))
         {
-            ChangeState(kState_None);
+            VERBOSE(VB_RECORD, LOC + "SPLIT: Finishing Previous Recording");
+            StopRecording(curRecordings.first());
+            if (curRecordings.isEmpty())
+                ChangeState(kState_None);
             ClearFlags(kFlagFinishRecording);
         }
 
-        if (curRecording)
-            curRecording->UpdateInUseMark();
+        for (ProgramInfo *rec = curRecordings.first();
+             rec; rec = curRecordings.next())
+        {
+            rec->UpdateInUseMark();
+        }
 
         // Check for the end of the current program..
         if (GetState() == kState_WatchingLiveTV)
         {
+            VERBOSE(VB_RECORD, LOC + "SPLIT: Watching LiveTV");
 #define LIVETV_END (now >= curRecording->endts)
 // use the following instead to test ringbuffer switching
 //static QDateTime last = QDateTime::currentDateTime(); 
@@ -1498,6 +1612,7 @@
         // state (either kState_RecordingOnly or kState_None).
         if (HasFlags(kFlagExitPlayer))
         {
+            VERBOSE(VB_RECORD, LOC + "SPLIT: Exit Player");
             if (internalState == kState_WatchingLiveTV)
                 ChangeState(kState_None);
             else if (StateIsPlaying(internalState))
@@ -1539,6 +1654,8 @@
         }
     }
   
+    VERBOSE(VB_RECORD, LOC + "SPLIT: RunTV exited while loop");
+
     if (GetState() != kState_None)
     {
         ChangeState(kState_None);
@@ -2316,13 +2433,13 @@
 bool TVRec::SetVideoFiltersForChannel(uint  sourceid,
                                       const QString &channum)
 {
-    if (!recorder)
+    if (!newRecorder)
         return false;
 
     QString videoFilters = ChannelUtil::GetVideoFilters(sourceid, channum);
     if (!videoFilters.isEmpty())
     {
-        recorder->SetVideoFilters(videoFilters);
+        newRecorder->SetVideoFilters(videoFilters);
         return true;
     }
 
@@ -2380,12 +2497,13 @@
  *  \sa EncoderLink::GetFramesWritten(), RemoteEncoder::GetFramesWritten()
  *  \return Number of frames if query succeeds, -1 otherwise.
  */
+// SPLIT this should take in a ProgramInfo *
 long long TVRec::GetFramesWritten(void)
 {
     QMutexLocker lock(&stateChangeLock);
 
-    if (recorder)
-        return recorder->GetFramesWritten();
+    if (newRecorder)
+        return newRecorder->GetFramesWritten();
     return -1;
 }
 
@@ -2411,12 +2529,13 @@
  *      RemoteEncoder::GetKeyframePosition(long long)
  *  \return Byte position of keyframe if query succeeds, -1 otherwise.
  */
+// SPLIT this thould take in a ProgramInfo *
 long long TVRec::GetKeyframePosition(long long desired)
 {
     QMutexLocker lock(&stateChangeLock);
 
-    if (recorder)
-        return recorder->GetKeyframePosition(desired);
+    if (newRecorder)
+        return newRecorder->GetKeyframePosition(desired);
     return -1;
 }
 
@@ -3159,8 +3278,8 @@
 {
     QMutexLocker lock(&stateChangeLock);
 
-    RingBuffer *rb_old = ringBuffer;
-    ringBuffer = rb;
+    RingBuffer *rb_old = newRingBuffer;
+    newRingBuffer = rb;
 
     if (rb_old && (rb_old != rb))
     {
@@ -3229,12 +3348,13 @@
     if (HasFlags(kFlagWaitingForRecPause))
     {
         VERBOSE(VB_RECORD, LOC + "RaceTrace: 6");
+        VERBOSE(VB_RECORD, LOC + QString("RecorderMux = %1").arg((unsigned int)recorderMux));
         if (!recorderMux->IsPaused())
             return;
 
         ClearFlags(kFlagWaitingForRecPause);
 #ifdef USING_DVB
-        if (GetDVBRecorder())
+        if (GetDVBRecorderMux() && GetDVBRecorder())
         {
             // We currently need to close the file descriptor for
             // DVB signal monitoring to work with some drivers
@@ -3525,6 +3645,7 @@
 
     if (use_dr)
     {
+        VERBOSE(VB_RECORD, LOC + "SPLIT: Using Dummy Recorder");
         // We need there to be a ringbuffer for these modes
         bool ok;
         ProgramInfo *tmp = pseudoLiveTVRecording;
@@ -3747,6 +3868,7 @@
 
     if (tvchain)
     {
+        VERBOSE(VB_RECORD, LOC + "SPLIT: Creating LiveTV RingBuffer");
         bool ok;
         if (!ringBuffer)
         {
@@ -3754,7 +3876,7 @@
             SetFlags(kFlagRingBufferReady);
         }
         else
-            ok = SwitchLiveTVRingBuffer(true, !had_dummyrec && recorder);
+            ok = SwitchLiveTVRingBuffer(true, !had_dummyrec && newRecorder);
         if (!ok)
         {
             VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create RingBuffer 2");
@@ -3766,7 +3888,7 @@
     if (lastTuningRequest.flags & kFlagRecording)
     {
         SetRingBuffer(new RingBuffer(rec->GetFileName(), true));
-        if (!ringBuffer->IsOpen())
+        if (!newRingBuffer->IsOpen())
         {
             VERBOSE(VB_IMPORTANT, LOC_ERR +
                     QString("RingBuffer '%1' not open...")
@@ -3777,10 +3899,10 @@
         }
     }
 
-    if (!ringBuffer)
+    if (!newRingBuffer)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
-                    "Failed to start recorder!  ringBuffer is NULL\n"
+                    "Failed to start recorder!  newRingBuffer is NULL\n"
                     "\t\t\t\t  Tuning request was %1\n")
                 .arg(lastTuningRequest.toString()));
 
@@ -3835,7 +3957,9 @@
         channel->Open(); // Needed because of NVR::MJPEGInit()
 
     if (rec)
-        recorder->SetRecording(rec);
+        newRecorder->SetRecording(rec);
+
+    DoneAddingRecording();
 
     // Setup for framebuffer capture devices..
     if (channel)
@@ -3905,12 +4029,12 @@
 
     SwitchLiveTVRingBuffer(true, !had_dummyrec);
 
-    recorderMux->Reset();
+    newRecorder->Reset();
     if (had_dummyrec)
     {
-        recorder->SetRingBuffer(ringBuffer);
+        newRecorder->SetRingBuffer(newRingBuffer);
         ProgramInfo *progInfo = tvchain->GetProgramAt(-1);
-        recorder->SetRecording(progInfo);
+        newRecorder->SetRecording(progInfo);
         delete progInfo;
     }
 
@@ -4190,11 +4314,11 @@
     tvchain->AppendNewProgram(pginfo, channel->GetCurrentName(),
                               channel->GetCurrentInput(), discont);
 
-    if (set_rec && recorder)
+    if (set_rec && newRecorder)
     {
-        recorder->SetNextRecording(pginfo, rb);
+        newRecorder->SetNextRecording(pginfo, rb);
         if (discont)
-            recorder->CheckForRingBufferSwitch();
+            newRecorder->CheckForRingBufferSwitch();
         delete pginfo;
         SetFlags(kFlagRingBufferReady);
     }
@@ -4209,6 +4333,21 @@
     return true;
 }
 
+void TVRec::DoneAddingRecording()
+{
+    VERBOSE(VB_RECORD, LOC + QString("Unlocking newRecordingLock for %1")
+                                .arg(newRecording->title));
+    curRecordings.append(newRecording);
+    curRecordings.Sort(comp_recend);
+    recordEndTime = GetRecordEndTime(curRecordings.getFirst());
+    ringBuffers[newRecording] = newRingBuffer;
+    recorders[newRecording] = newRecorder;
+    newRecording = NULL;
+    newRingBuffer = NULL;
+    newRecorder = NULL;
+    newRecordingLock.unlock();
+}
+
 QString TuningRequest::toString(void) const
 {
     return QString("Program(%1) channel(%2) input(%3) flags(%4)")
Index: mythtv/libs/libmythtv/recorderbase.h
===================================================================
--- mythtv.orig/libs/libmythtv/recorderbase.h	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/recorderbase.h	2006-05-21 14:47:33.000000000 +1000
@@ -57,6 +57,11 @@
      */
     void SetRingBuffer(RingBuffer *rbuf);
 
+    /** \brief StopRecording() removes this recorder from the list of
+     *         current recorders in RecorderMuxBase recorder list.
+     */
+    virtual void StopRecording();
+
     /** \brief Set an specific option.
      *
      *   Base options include: codec, audiodevice, videodevice, vbidevice,
Index: mythtv/libs/libmythtv/recordermuxbase.h
===================================================================
--- mythtv.orig/libs/libmythtv/recordermuxbase.h	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/recordermuxbase.h	2006-05-21 14:47:33.000000000 +1000
@@ -38,6 +38,8 @@
     RecorderMuxBase(TVRec *rec);
     virtual ~RecorderMuxBase();
 
+    void RemoveRecording(RecorderBase *rec);
+
     /// \brief Sets the video frame rate.
     void SetFrameRate(double rate)
     {
@@ -157,7 +159,8 @@
     virtual bool PauseAndWait(int timeout = 100);
 
     TVRec         *tvrec;
-    RecorderBase  *recorder;    // SPLIT this should be a QPtrList<RecorderBase>
+    QPtrList<RecorderBase>  recorders;
+    QMutex                  recLock;
 
     QString        audiodevice;
     QString        videodevice;
Index: mythtv/libs/libmythtv/recorderbase.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/recorderbase.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/recorderbase.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -101,6 +101,11 @@
                     "SetStrOption(...%1): Option not in profile.").arg(name));
 }
 
+void RecorderBase::StopRecording()
+{
+    recMux->RemoveRecording(this);
+}
+
 void RecorderBase::CheckForRingBufferSwitch(void)
 {
     nextRingBufferLock.lock();
Index: mythtv/libs/libmythtv/recordermuxbase.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/recordermuxbase.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/recordermuxbase.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -13,7 +13,7 @@
 #define LOC_ERR QString("RecMuxBase(%1) Error: ").arg(videodevice)
 
 RecorderMuxBase::RecorderMuxBase(TVRec *rec)
-    : tvrec(rec), recorder(NULL),
+    : tvrec(rec),
       audiodevice("/dev/dsp"), videodevice("/dev/video"), vbidevice("/dev/vbi"),
       vbimode(0), ntsc(true), ntsc_framerate(true), video_frame_rate(29.97),
       request_pause(false), paused(false)
@@ -24,6 +24,24 @@
 
 RecorderMuxBase::~RecorderMuxBase(void)
 {
+    recLock.lock();
+    recorders.setAutoDelete(true);
+    recLock.unlock();
+}
+
+void RecorderMuxBase::RemoveRecording(RecorderBase *rec)
+{
+    QMutexLocker locker(&recLock);
+
+    QString msg = QString("Trying to remove %1 from:").arg((unsigned int)rec);
+    for (RecorderBase *r = recorders.first(); r; r = recorders.next())
+        msg += QString("\n%1").arg((unsigned int)r);
+    VERBOSE(VB_RECORD, msg);
+
+    rec->FinishRecording();
+    recorders.remove(rec);
+    if (recorders.isEmpty())
+        StopRecording();
 }
 
 void RecorderMuxBase::SetOption(const QString &name, const QString &value)
Index: mythtv/libs/libmythtv/programinfo.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/programinfo.cpp	2006-04-30 16:00:02.000000000 +1000
+++ mythtv/libs/libmythtv/programinfo.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -1524,6 +1524,7 @@
                            const ProgramInfo        *pg,
                            const ScheduledRecording *schd)
 {
+    VERBOSE(VB_RECORD, QString("Inserting \"%1\" into recorded").arg(pg->title));
     query.prepare("LOCK TABLES recorded WRITE");
     if (!query.exec())
     {
@@ -3893,6 +3894,47 @@
  *                                                                           *
  * ************************************************************************* */
 
+void ProgramList::ToStringList(QStringList &list) const
+{
+    char tmp[64];
+
+    // you can't iterate over a const QPtrList, copy it and iterate over
+    // the copy to keep this function const
+    ProgramList t(*this);
+
+    INT_TO_LIST(t.count());
+    for (ProgramInfo *pginfo = t.first(); pginfo; pginfo = t.next())
+    {
+        pginfo->ToStringList(list);
+    }
+}
+
+bool ProgramList::FromStringList(QStringList &list, int offset)
+{
+    QStringList::iterator it = list.at(offset);
+    return FromStringList(list, it);
+}
+
+bool ProgramList::FromStringList(QStringList &list, QStringList::iterator &it)
+{
+    const char *listerror = "ProgramList::FromStringList, not enough items "
+                            "in list.\n";
+    QStringList::iterator listend = list.end();
+    QString ts;
+    int progCount;
+
+    INT_FROM_LIST(progCount)
+
+    for (int i = 0; i < progCount; i++)
+    {
+        ProgramInfo *pginfo = new ProgramInfo;
+        pginfo->FromStringList(list, it);
+        append(pginfo);
+    }
+
+    return true;
+}
+
 bool ProgramList::FromScheduler(bool &hasConflicts, QString rectable,
                                 int recordid)
 {
Index: mythtv/libs/libmythtv/programinfo.h
===================================================================
--- mythtv.orig/libs/libmythtv/programinfo.h	2006-04-30 16:00:02.000000000 +1000
+++ mythtv/libs/libmythtv/programinfo.h	2006-05-21 14:47:33.000000000 +1000
@@ -338,6 +338,10 @@
         return at(index);
     };
 
+    void ToStringList(QStringList &list) const;
+    bool FromStringList(QStringList &list, int offset);
+    bool FromStringList(QStringList &list, QStringList::iterator &it);
+
     bool FromScheduler(bool &hasConflicts, QString altTable = "", int recordid=-1);
     bool FromScheduler(void) {
         bool dummyConflicts;
Index: mythtv/libs/libmythtv/mpegrecorder.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/mpegrecorder.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/mpegrecorder.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -40,9 +40,9 @@
 #endif
 }
 
-#define LOC QString("MPEGRec(%1): ").arg(videodevice)
-#define LOC_WARN QString("MPEGRec(%1) Warning: ").arg(videodevice)
-#define LOC_ERR QString("MPEGRec(%1) Error: ").arg(videodevice)
+#define LOC QString("MPEGRec(%1): ").arg((unsigned int)this)
+#define LOC_WARN QString("MPEGRec(%1) Warning: ").arg((unsigned int)this)
+#define LOC_ERR QString("MPEGRec(%1) Error: ").arg((unsigned int)this)
 
 MpegRecorder::MpegRecorder(TVRec *rec, MpegRecorderMux *mux) :
     RecorderBase(rec, mux),
@@ -54,6 +54,7 @@
     // Position map support
     positionMapLock(false)
 {
+    VERBOSE(VB_RECORD, LOC + QString("MpegRecorder ctor"));
 }
 
 MpegRecorder::~MpegRecorder()
Index: mythtv/libs/libmythtv/mpegrecordermux.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/mpegrecordermux.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/mpegrecordermux.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -486,10 +486,13 @@
         if (PauseAndWait(100))
             continue;
 
-        if ((deviceIsMpegFile) && (dynamic_cast<MpegRecorder*>(recorder)->framesWritten))
+        // This code limits the rate at which frames are written from an MPEG
+        // file.  Use a local count of the total number of frames written by
+        // this mux thread.
+        if (deviceIsMpegFile && framesWritten)
         {
             elapsed = (elapsedTimer.elapsed() / 1000.0) + 1;
-            while ((dynamic_cast<MpegRecorder*>(recorder)->framesWritten / elapsed) > 30)
+            while ((framesWritten / elapsed) > 30)
             {
                 usleep(50000);
                 elapsed = (elapsedTimer.elapsed() / 1000.0) + 1;
@@ -557,8 +560,6 @@
         }
     }
 
-    recorder->FinishRecording();
-
     delete[] buffer;
     recording = false;
 
@@ -567,16 +568,17 @@
 
 RecorderBase *MpegRecorderMux::CreateNewRecorder(TVRec *tvrec)
 {
-    recorder = new MpegRecorder(tvrec, this);
-    return recorder;
+    MpegRecorder *rec = new MpegRecorder(tvrec, this);
+    recLock.lock();
+    recorders.append(rec);
+    recLock.unlock();
+    return rec;
 }
 
 bool MpegRecorderMux::SetupRecording(void)
 {
     leftovers = 0xFFFFFFFF;
-    VERBOSE(VB_RECORD, QString("recorder = %1").arg((int)recorder));
-    dynamic_cast<MpegRecorder*>(recorder)->numgops = 0;
-    dynamic_cast<MpegRecorder*>(recorder)->lastseqstart = 0;
+    VERBOSE(VB_RECORD, QString("recorder = %1").arg((unsigned int)this));
     return true;
 }
 
@@ -594,6 +596,8 @@
 
     while (bufptr < buffer + len)
     {
+        recLock.lock();
+
         v = *bufptr++;
         if (state == 0x000001)
         {
@@ -601,9 +605,12 @@
             
             if (state == PACK_HEADER)
             {
-                long long startpos = recorder->ringBuffer->GetWritePosition();
-                startpos += buildbuffersize + bufptr - bufstart - 4;
-                dynamic_cast<MpegRecorder*>(recorder)->lastpackheaderpos = startpos;
+                long long startpos = buildbuffersize + bufptr - bufstart - 4;
+
+                for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());             rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
+                {
+                    rec->lastpackheaderpos = rec->ringBuffer->GetWritePosition() + startpos;
+                }
 
                 int curpos = bufptr - bufstart - 4;
                 if (curpos < 0)
@@ -611,7 +618,12 @@
                     // header was split
                     buildbuffersize += curpos;
                     if (buildbuffersize > 0)
-                        recorder->ringBuffer->Write(buildbuffer, buildbuffersize);
+                    {
+                        for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());              rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
+                        {
+                            rec->ringBuffer->Write(buildbuffer, buildbuffersize);
+                        }
+                    }
 
                     buildbuffersize = 4;
                     memcpy(buildbuffer, &state, 4);
@@ -628,7 +640,12 @@
                     leftlen -= curpos;
 
                     if (buildbuffersize > 0)
-                        recorder->ringBuffer->Write(buildbuffer, buildbuffersize);
+                    {
+                        for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());              rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
+                        {
+                            rec->ringBuffer->Write(buildbuffer, buildbuffersize);
+                        }
+                    }
 
                     buildbuffersize = 0;
                 }
@@ -636,25 +653,47 @@
 
             if (state == SEQ_START)
             {
-                dynamic_cast<MpegRecorder*>(recorder)->lastseqstart = dynamic_cast<MpegRecorder*>(recorder)->lastpackheaderpos;
+                for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());              rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
+                {
+                    rec->lastseqstart = rec->lastpackheaderpos;
+                }
             }
 
-            if (state == GOP_START && dynamic_cast<MpegRecorder*>(recorder)->lastseqstart == dynamic_cast<MpegRecorder*>(recorder)->lastpackheaderpos)
+            for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());              rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
             {
-                dynamic_cast<MpegRecorder*>(recorder)->framesWritten = dynamic_cast<MpegRecorder*>(recorder)->numgops * keyframedist;
-                dynamic_cast<MpegRecorder*>(recorder)->numgops++;
-                dynamic_cast<MpegRecorder*>(recorder)->HandleKeyframe();
+                if (state == GOP_START &&
+                    rec->lastseqstart == rec->lastpackheaderpos)
+                {
+                    if (rec == dynamic_cast<MpegRecorder*>(recorders.getFirst()))
+                    {
+                        // count the number of frames written by this mux
+                        framesWritten = numgops * keyframedist;
+                        numgops++;
+                    }
+
+                    rec->framesWritten = rec->numgops * keyframedist;
+                    rec->numgops++;
+                    rec->HandleKeyframe();
+                }
             }
         }
         else
             state = ((state << 8) | v) & 0xFFFFFF;
+
+        recLock.unlock();
     }
 
     leftovers = state;
 
     if (buildbuffersize + leftlen > kBuildBufferMaxSize)
     {
-        recorder->ringBuffer->Write(buildbuffer, buildbuffersize);
+        recLock.lock();
+        for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());
+             rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
+        {
+            rec->ringBuffer->Write(buildbuffer, buildbuffersize);
+        }
+        recLock.unlock();
         buildbuffersize = 0;
     }
 
@@ -670,7 +709,14 @@
 
 void MpegRecorderMux::Reset(void)
 {
-    dynamic_cast<MpegRecorder*>(recorder)->Reset();
+    // reset all recorders
+    recLock.lock();
+    for (MpegRecorder *rec = dynamic_cast<MpegRecorder*>(recorders.first());
+         rec; rec = dynamic_cast<MpegRecorder*>(recorders.next()))
+    {
+        rec->Reset();
+    }
+    recLock.unlock();
 
     leftovers = 0xFFFFFFFF;
     buildbuffersize = 0;
Index: mythtv/libs/libmythtv/NuppelVideoRecorderMux.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/NuppelVideoRecorderMux.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/NuppelVideoRecorderMux.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -125,6 +125,8 @@
 
     go7007 = false;
     resetcapture = false;
+
+    recorder = NULL;
 }
 
 NuppelVideoRecorderMux::~NuppelVideoRecorderMux(void)
Index: mythtv/libs/libmythtv/NuppelVideoRecorderMux.h
===================================================================
--- mythtv.orig/libs/libmythtv/NuppelVideoRecorderMux.h	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/NuppelVideoRecorderMux.h	2006-05-21 14:47:33.000000000 +1000
@@ -195,6 +195,9 @@
 
     bool go7007;
     bool resetcapture;
+
+    // SPLIT delete this
+    RecorderBase *recorder;
 };
 
 #endif
Index: mythtv/programs/mythbackend/encoderlink.cpp
===================================================================
--- mythtv.orig/programs/mythbackend/encoderlink.cpp	2006-05-21 14:39:20.000000000 +1000
+++ mythtv/programs/mythbackend/encoderlink.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -162,14 +162,14 @@
  *  \brief Returns true if rec is actually being recorded by TVRec.
  *  
  *   This waits for TVRec to enter a state other than kState_ChangingState
- *   Then it checks TVRec::GetRecording() against rec.
- *  \param rec Recording to check against TVRec::GetRecording().
+ *   Then it checks TVRec::GetRecordings() against rec.
+ *  \param rec Recording to check against TVRec::GetRecordings().
  *  \sa IsRecording(const ProgramInfo*)
  */
 bool EncoderLink::MatchesRecording(const ProgramInfo *rec)
 {
     bool retval = false;
-    ProgramInfo *tvrec = NULL;
+    ProgramList tvrecList;
 
     if (local)
     {
@@ -177,9 +177,9 @@
             usleep(100);
 
         if (IsBusyRecording())
-            tvrec = tv->GetRecording();
+            tvrecList = tv->GetRecordings();
 
-        if (tvrec)
+        for (ProgramInfo *tvrec = tvrecList.first(); tvrec; tvrec = tvrecList.current())
         {
             if (tvrec->chanid == rec->chanid && 
                 tvrec->recstartts == rec->recstartts)
@@ -187,6 +187,7 @@
                 retval = true;
             }
 
+            tvrecList.removeFirst();
             delete tvrec;
         }
     }
@@ -394,7 +395,7 @@
  *
  *  \return +1 if the recording started successfully,
  *          -1 if TVRec is busy doing something else, 0 otherwise.
- *  \sa RecordPending(const ProgramInfo*, int), StopRecording()
+ *  \sa RecordPending(const ProgramInfo*, int), StopRecording(ProgramInfo *)
  */
 RecStatusType EncoderLink::StartRecording(const ProgramInfo *rec)
 {
@@ -424,30 +425,29 @@
     return retval;
 }
 
-/** \fn EncoderLink::GetRecording()
- *  \brief Returns TVRec's current recording.
+/** \fn EncoderLink::GetRecordings()
+ *  \brief Returns TVRec's current recordings.
  *
- *   Caller is responsible for deleting the ProgramInfo when done with it.
+ *   Caller is responsible for deleting the %ProgramInfo items in the
+ *   %ProgramList when done with it.
  *  \return Returns TVRec's current recording if it succeeds, NULL otherwise.
  */
-ProgramInfo *EncoderLink::GetRecording(void)
+ProgramList EncoderLink::GetRecordings(void)
 {
-    ProgramInfo *info = NULL;
-
     if (local)
-        info = tv->GetRecording();
+        return tv->GetRecordings();
     else if (sock)
-        info = sock->GetRecording(m_capturecardnum);
-
-    return info;
+        return sock->GetRecordings(m_capturecardnum);
+    else
+        return ProgramList(false);
 }
 
-/** \fn EncoderLink::StopRecording()
+/** \fn EncoderLink::StopRecording(ProgramInfo *)
  *  \brief Tells TVRec to stop recording immediately.
  *         <b>This only works on local recorders.</b>
  *  \sa StartRecording(const ProgramInfo *rec), FinishRecording()
  */
-void EncoderLink::StopRecording(void)
+void EncoderLink::StopRecording(ProgramInfo *rec)
 {
     endRecordingTime = QDateTime::currentDateTime().addDays(-2);
     startRecordingTime = endRecordingTime;
@@ -455,7 +455,7 @@
 
     if (local)
     {
-        tv->StopRecording();
+        tv->StopRecording(rec);
         return;
     }
 }
@@ -463,7 +463,7 @@
 /** \fn EncoderLink::FinishRecording()
  *  \brief Tells TVRec to stop recording, but only after "overrecord" seconds.
  *         <b>This only works on local recorders.</b>
- *  \sa StopRecording()
+ *  \sa StopRecording(ProgramInfo *)
  */
 void EncoderLink::FinishRecording(void)
 {
Index: mythtv/programs/mythbackend/encoderlink.h
===================================================================
--- mythtv.orig/programs/mythbackend/encoderlink.h	2006-05-21 14:39:20.000000000 +1000
+++ mythtv/programs/mythbackend/encoderlink.h	2006-05-21 14:47:33.000000000 +1000
@@ -61,14 +61,14 @@
     bool MatchesRecording(const ProgramInfo *rec);
     void RecordPending(const ProgramInfo *rec, int secsleft);
     RecStatusType StartRecording(const ProgramInfo *rec);
-    void StopRecording(void);
+    void StopRecording(ProgramInfo *rec);
     void FinishRecording(void);
     void FrontendReady(void);
     void CancelNextRecording(bool);
     bool WouldConflict(const ProgramInfo *rec);
 
     bool IsReallyRecording(void);
-    ProgramInfo *GetRecording(void);
+    ProgramList GetRecordings(void);
     float GetFramerate(void);
     long long GetFramesWritten(void);
     long long GetFilePosition(void);
Index: mythtv/programs/mythbackend/mainserver.cpp
===================================================================
--- mythtv.orig/programs/mythbackend/mainserver.cpp	2006-05-21 14:42:14.000000000 +1000
+++ mythtv/programs/mythbackend/mainserver.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -1012,7 +1012,8 @@
                        "LEFT JOIN record ON recorded.recordid = record.recordid "
                        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
                        "LEFT JOIN recordedprogram ON (recorded.chanid = recordedprogram.chanid "
-                              "AND recorded.starttime = recordedprogram.starttime) "
+                              "AND recorded.starttime = recordedprogram.starttime "
+                              "AND recorded.title = recordedprogram.title) "
                        "WHERE (recorded.deletepending = 0 OR "
                               "DATE_ADD(recorded.lastmodified, "
                                        "INTERVAL 5 MINUTE) <= NOW()) "
@@ -1567,7 +1568,7 @@
 
             if (num > 0)
             {
-                (*encoderList)[num]->StopRecording();
+                (*encoderList)[num]->StopRecording(pginfo);
                 pginfo->recstatus = rsRecorded;
                 if (m_sched)
                     m_sched->UpdateRecStatus(pginfo);
@@ -1606,7 +1607,7 @@
         {
             recnum = iter.key();
 
-            elink->StopRecording();
+            elink->StopRecording(pginfo);
 
             while (elink->IsBusyRecording() ||
                    elink->GetState() == kState_ChangingState)
@@ -1666,7 +1667,7 @@
 
             if (num > 0)
             {
-                (*encoderList)[num]->StopRecording();
+                (*encoderList)[num]->StopRecording(pginfo);
                 pginfo->recstatus = rsRecorded;
                 if (m_sched)
                     m_sched->UpdateRecStatus(pginfo);
@@ -1696,7 +1697,7 @@
         {
             resultCode = iter.key();
 
-            elink->StopRecording();
+            elink->StopRecording(pginfo);
 
             while (elink->IsBusyRecording() || 
                    elink->GetState() == kState_ChangingState)
@@ -2438,11 +2439,13 @@
         long long value = enc->GetMaxBitrate();
         encodeLongLong(retlist, value);
     }
-    else if (command == "GET_CURRENT_RECORDING")
+    else if (command == "GET_CURRENT_RECORDINGS")
     {
-        ProgramInfo *info = enc->GetRecording();
-        info->ToStringList(retlist);
-        delete info;
+        ProgramList info = enc->GetRecordings();
+        info.ToStringList(retlist);
+
+        for (ProgramInfo *pginfo = info.first(); pginfo; pginfo = info.next())
+            delete pginfo;
     }
     else if (command == "GET_KEYFRAME_POS")
     {
@@ -2469,19 +2472,13 @@
         if (!retlist.size())
             retlist << "ok";
     }
-    else if (command == "GET_RECORDING")
+    else if (command == "GET_RECORDINGS")
     {
-        ProgramInfo *pginfo = enc->GetRecording();
-        if (pginfo)
-        {
-            pginfo->ToStringList(retlist);
+        ProgramList info = enc->GetRecordings();
+        info.ToStringList(retlist);
+
+        for (ProgramInfo *pginfo = info.first(); pginfo; pginfo = info.next())
             delete pginfo;
-        }
-        else
-        {
-            ProgramInfo dummy;
-            dummy.ToStringList(retlist);
-        }
     }
     else if (command == "FRONTEND_READY")
     {
@@ -2787,11 +2784,13 @@
         long long value = enc->GetMaxBitrate();
         encodeLongLong(retlist, value);
     }
-    else if (command == "GET_CURRENT_RECORDING")
+    else if (command == "GET_CURRENT_RECORDINGS")
     {
-        ProgramInfo *info = enc->GetRecording();
-        info->ToStringList(retlist);
-        delete info;
+        ProgramList info = enc->GetRecordings();
+        info.ToStringList(retlist);
+
+        for (ProgramInfo *pginfo = info.first(); pginfo; pginfo = info.next())
+            delete pginfo;
     }
 
     SendResponse(pbssock, retlist);
@@ -3699,9 +3698,11 @@
     {
         EncoderLink *elink = iter.data();
         elink->CancelNextRecording(true);
-        ProgramInfo *pinfo = elink->GetRecording();
-        pinfo->ToStringList(strlist);
-        delete pinfo;
+        ProgramList info = elink->GetRecordings();
+        info.ToStringList(strlist);
+
+        for (ProgramInfo *pginfo = info.first(); pginfo; pginfo = info.next())
+            delete pginfo;
     }
 
     WriteStringList(masterServerSock, strlist);
@@ -3871,9 +3872,9 @@
                 case kState_RecordingOnly:
                 case kState_WatchingRecording:
                 {
-                    ProgramInfo *pInfo = elink->GetRecording();
+                    ProgramList info = elink->GetRecordings();
 
-                    if (pInfo)
+                    for (ProgramInfo *pInfo = info.first(); pInfo; pInfo = info.next())
                     {
                         FillProgramInfo(pDoc, encoder, pInfo);
                         delete pInfo;
Index: mythtv/programs/mythbackend/playbacksock.cpp
===================================================================
--- mythtv.orig/programs/mythbackend/playbacksock.cpp	2006-04-30 16:00:02.000000000 +1000
+++ mythtv/programs/mythbackend/playbacksock.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -217,23 +217,24 @@
     return ret;
 }
 
-/** \fn *PlaybackSock::GetRecording(int)
- *  \brief Returns the ProgramInfo being used by any current recording.
+/** \fn *PlaybackSock::GetRecordings(int)
+ *  \brief Returns the ProgramList being used by any current recording.
  *
- *   Caller is responsible for deleting the ProgramInfo when done with it.
+ *   Caller is responsible for deleting the ProgramInfo in the ProgramList
+ *   when done with it.
  *  \param capturecardnum cardid of recorder
  */
-ProgramInfo *PlaybackSock::GetRecording(int capturecardnum)
+ProgramList PlaybackSock::GetRecordings(int capturecardnum)
 {
     QStringList strlist = QString("QUERY_REMOTEENCODER %1")
         .arg(capturecardnum);
 
-    strlist << "GET_CURRENT_RECORDING";
+    strlist << "GET_CURRENT_RECORDINGS";
 
     SendReceiveStringList(strlist);
 
-    ProgramInfo *info = new ProgramInfo();
-    info->FromStringList(strlist, 0);
+    ProgramList info(false);
+    info.FromStringList(strlist, 0);
     return info;
 }
 
Index: mythtv/programs/mythbackend/playbacksock.h
===================================================================
--- mythtv.orig/programs/mythbackend/playbacksock.h	2006-04-30 16:00:02.000000000 +1000
+++ mythtv/programs/mythbackend/playbacksock.h	2006-05-21 14:47:33.000000000 +1000
@@ -54,7 +54,7 @@
     bool IsBusy(int capturecardnum);
     int GetEncoderState(int capturecardnum);
     long long GetMaxBitrate(int capturecardnum);
-    ProgramInfo *GetRecording(int capturecardnum);
+    ProgramList GetRecordings(int capturecardnum);
     bool EncoderIsRecording(int capturecardnum, const ProgramInfo *pginfo);
     RecStatusType StartRecording(int capturecardnum, 
                                  const ProgramInfo *pginfo);
Index: mythtv/libs/libmythtv/dtvrecordermux.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/dtvrecordermux.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/dtvrecordermux.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -11,6 +11,7 @@
 #include "programinfo.h"
 #include "mpegtables.h"
 #include "dtvrecordermux.h"
+#include "dtvrecorder.h"
 #include "recorderbase.h"
 #include "tv_rec.h"
 
@@ -90,7 +91,13 @@
 // documented in recorderbase.h
 void DTVRecorderMux::Reset(void)
 {
-    recorder->Reset();
+    // reset all recorders
+    recLock.lock();
+    for (DTVRecorder *rec = dynamic_cast<DTVRecorder*>(recorders.first());
+         rec; rec = dynamic_cast<DTVRecorder*>(recorders.next()))
+    {
+        rec->Reset();
+    }
 
     //_recording
     _error                      = false;
Index: mythtv/libs/libmythtv/dvbrecordermux.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/dvbrecordermux.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/dvbrecordermux.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -243,8 +243,11 @@
 
 RecorderBase *DVBRecorderMux::CreateNewRecorder(TVRec *tvrec)
 {
-    recorder = new DVBRecorder(tvrec, this);
-    return recorder;
+    DVBRecorder *rec = new DVBRecorder(tvrec, this);
+    recLock.lock();
+    recorders.append(rec);
+    recLock.unlock();
+    return rec;
 }
 
 void DVBRecorderMux::CloseFilters(void)
@@ -475,8 +478,6 @@
 
     Close();
 
-    recorder->FinishRecording();
-
     _recording = false;
 }
 
@@ -486,21 +487,33 @@
     {
         QMutexLocker read_lock(&_pid_lock);
         uint next_cc;
-        if (_pat && _pmt && recorder)
+        if (_pat && _pmt)
         {
+            recLock.lock();
+
             next_cc = (_pat->tsheader()->ContinuityCounter()+1)&0xf;
             _pat->tsheader()->SetContinuityCounter(next_cc);
-            dynamic_cast<DVBRecorder*>(recorder)->BufferedWrite(*(reinterpret_cast<TSPacket*>(_pat->tsheader())));
+            for (DVBRecorder *rec = dynamic_cast<DVBRecorder*>(recorders.first());
+                 rec; rec = dynamic_cast<DVBRecorder*>(recorders.next()))
+            {
+                rec->BufferedWrite(*(reinterpret_cast<TSPacket*>(_pat->tsheader())));
+            }
 
             unsigned char buf[8 * 1024];
             uint cc = _pmt->tsheader()->ContinuityCounter();
             uint size = _pmt->WriteAsTSPackets(buf, cc);
             _pmt->tsheader()->SetContinuityCounter(cc);
 
-            for (uint i = 0; i < size ; i += TSPacket::SIZE)
-                dynamic_cast<DVBRecorder*>(recorder)->BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i])));
+            for (DVBRecorder *rec = dynamic_cast<DVBRecorder*>(recorders.first());
+                 rec; rec = dynamic_cast<DVBRecorder*>(recorders.next()))
+            {
+                for (uint i = 0; i < size ; i += TSPacket::SIZE)
+                    rec->BufferedWrite(*(reinterpret_cast<TSPacket*>(&buf[i])));
+            }
 
             _ts_packets_until_psip_sync = TSPACKETS_BETWEEN_PSIP_SYNC;
+
+            recLock.unlock();
         }
     }
     else
@@ -750,11 +763,22 @@
 
     // Check for keyframes and count frames
     if (info->isVideo)
-        dynamic_cast<DVBRecorder*>(recorder)->_buffer_packets = !dynamic_cast<DVBRecorder*>(recorder)->FindKeyframes(&tspacket);
+    {
+        recLock.lock();
+        for (DVBRecorder *rec = dynamic_cast<DVBRecorder*>(recorders.first());
+             rec; rec = dynamic_cast<DVBRecorder*>(recorders.next()))
+        {
+            rec->_buffer_packets = !rec->FindKeyframes(&tspacket);
+        }
+        recLock.unlock();
+    }
 
+    // SPLIT this needs to be modified
     // Sync recording start to first keyframe
+#if 0
     if (_wait_for_keyframe_option && dynamic_cast<DVBRecorder*>(recorder)->_first_keyframe<0)
         return;
+#endif
 
     // Sync streams to the first Payload Unit Start Indicator
     // _after_ first keyframe iff _wait_for_keyframe_option is true
@@ -772,7 +796,13 @@
     WritePATPMT();
 
     // Write Data
-    dynamic_cast<DVBRecorder*>(recorder)->BufferedWrite(tspacket);
+    recLock.lock();
+    for (DVBRecorder *rec = dynamic_cast<DVBRecorder*>(recorders.first());
+         rec; rec = dynamic_cast<DVBRecorder*>(recorders.next()))
+    {
+        rec->BufferedWrite(tspacket);
+    }
+    recLock.unlock();
 }
 
 void DVBRecorderMux::GetTimeStamp(const TSPacket& tspacket)
Index: mythtv/libs/libmythtv/hdtvrecordermux.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/hdtvrecordermux.cpp	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/hdtvrecordermux.cpp	2006-05-21 14:47:33.000000000 +1000
@@ -115,6 +115,7 @@
       _atsc_stream_data(NULL),
       _resync_count(0)
 {
+    recorder = NULL;
     SetStreamData(new ATSCStreamData(-1, DEFAULT_SUBCHANNEL));
 
     _buffer_size = TSPacket::SIZE * 1500;
Index: mythtv/libs/libmythtv/hdtvrecordermux.h
===================================================================
--- mythtv.orig/libs/libmythtv/hdtvrecordermux.h	2006-05-21 14:44:28.000000000 +1000
+++ mythtv/libs/libmythtv/hdtvrecordermux.h	2006-05-21 14:47:33.000000000 +1000
@@ -106,6 +106,8 @@
         unsigned char  * writePtr;
         unsigned char  * endPtr;
     } ringbuf;
+
+    RecorderBase *recorder;
 };
 
 #endif
