diff --git a/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp b/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp
index db9f694..32506e4 100644
--- a/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp
+++ b/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp
@@ -831,7 +831,7 @@ void MPEGStreamData::ProcessPAT(const ProgramAssociationTable *pat)
         QMutexLocker locker(&_listener_lock);
         ProgramAssociationTable *pat_sp = PATSingleProgram();
         for (uint i = 0; i < _mpeg_sp_listeners.size(); i++)
-            _mpeg_sp_listeners[i]->HandleSingleProgramPAT(pat_sp);
+            _mpeg_sp_listeners[i]->HandleSingleProgramPAT(pat_sp, false);
     }
 }
 
@@ -866,7 +866,7 @@ void MPEGStreamData::ProcessPMT(const ProgramMapTable *pmt)
         QMutexLocker locker(&_listener_lock);
         ProgramMapTable *pmt_sp = PMTSingleProgram();
         for (uint i = 0; i < _mpeg_sp_listeners.size(); i++)
-            _mpeg_sp_listeners[i]->HandleSingleProgramPMT(pmt_sp);
+            _mpeg_sp_listeners[i]->HandleSingleProgramPMT(pmt_sp, false);
     }
 }
 
@@ -977,7 +977,7 @@ void MPEGStreamData::HandleTSTables(const TSPacket* tspacket)
             QMutexLocker locker(&_listener_lock);
             ProgramAssociationTable *pat_sp = PATSingleProgram();
             for (uint i = 0; i < _mpeg_sp_listeners.size(); i++)
-                _mpeg_sp_listeners[i]->HandleSingleProgramPAT(pat_sp);
+                _mpeg_sp_listeners[i]->HandleSingleProgramPAT(pat_sp, false);
         }
         if (TableID::PMT == psip->TableID() &&
             tspacket->PID() == _pid_pmt_single_program)
@@ -985,7 +985,7 @@ void MPEGStreamData::HandleTSTables(const TSPacket* tspacket)
             QMutexLocker locker(&_listener_lock);
             ProgramMapTable *pmt_sp = PMTSingleProgram();
             for (uint i = 0; i < _mpeg_sp_listeners.size(); i++)
-                _mpeg_sp_listeners[i]->HandleSingleProgramPMT(pmt_sp);
+                _mpeg_sp_listeners[i]->HandleSingleProgramPMT(pmt_sp, false);
         }
         DONE_WITH_PSIP_PACKET(); // already parsed this table, toss it.
     }
diff --git a/mythtv/libs/libmythtv/mpeg/streamlisteners.h b/mythtv/libs/libmythtv/mpeg/streamlisteners.h
index b217860..0e4127f 100644
--- a/mythtv/libs/libmythtv/mpeg/streamlisteners.h
+++ b/mythtv/libs/libmythtv/mpeg/streamlisteners.h
@@ -95,8 +95,9 @@ class MPEGSingleProgramStreamListener
   protected:
     virtual ~MPEGSingleProgramStreamListener() {}
   public:
-    virtual void HandleSingleProgramPAT(ProgramAssociationTable*) = 0;
-    virtual void HandleSingleProgramPMT(ProgramMapTable*) = 0;
+    virtual void HandleSingleProgramPAT(ProgramAssociationTable*,
+                                        bool insert) = 0;
+    virtual void HandleSingleProgramPMT(ProgramMapTable*, bool insert) = 0;
 };
 
 class ATSCMainStreamListener
diff --git a/mythtv/libs/libmythtv/recorders/asirecorder.cpp b/mythtv/libs/libmythtv/recorders/asirecorder.cpp
index 148d1d5..640ebc3 100644
--- a/mythtv/libs/libmythtv/recorders/asirecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/asirecorder.cpp
@@ -65,6 +65,14 @@ void ASIRecorder::SetOption(const QString &name, int value)
         DTVRecorder::SetOption(name, value);
 }
 
+void ASIRecorder::StartNewFile(void)
+{
+    // Make sure the first things in the file are a PAT & PMT
+    HandleSingleProgramPAT(_stream_data->PATSingleProgram(), true);
+    HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), true);
+}
+
+
 void ASIRecorder::run(void)
 {
     if (!Open())
@@ -102,12 +110,7 @@ void ASIRecorder::run(void)
     if (m_channel && (m_channel->GetSIStandard() == "dvb"))
         _stream_data->AddListeningPID(DVB_TDT_PID);
 
-    // Make sure the first things in the file are a PAT & PMT
-    bool tmp = _wait_for_keyframe_option;
-    _wait_for_keyframe_option = false;
-    HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-    HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
-    _wait_for_keyframe_option = tmp;
+    StartNewFile();
 
     _stream_data->AddAVListener(this);
     _stream_data->AddWritingListener(this);
diff --git a/mythtv/libs/libmythtv/recorders/asirecorder.h b/mythtv/libs/libmythtv/recorders/asirecorder.h
index a973f9d..22d52b9 100644
--- a/mythtv/libs/libmythtv/recorders/asirecorder.h
+++ b/mythtv/libs/libmythtv/recorders/asirecorder.h
@@ -69,6 +69,7 @@ class ASIRecorder : public DTVRecorder
     bool Open(void);
     bool IsOpen(void) const;
     void Close(void);
+    void StartNewFile(void);
 
   private:
     ASIChannel       *m_channel;
diff --git a/mythtv/libs/libmythtv/recorders/cetonrecorder.cpp b/mythtv/libs/libmythtv/recorders/cetonrecorder.cpp
index 8910c66..51c9a57 100644
--- a/mythtv/libs/libmythtv/recorders/cetonrecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/cetonrecorder.cpp
@@ -47,6 +47,13 @@ void CetonRecorder::Close(void)
     LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
 }
 
+void CetonRecorder::StartNewFile(void)
+{
+    // Make sure the first things in the file are a PAT & PMT
+    HandleSingleProgramPAT(_stream_data->PATSingleProgram(), true);
+    HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), true);
+}
+
 void CetonRecorder::run(void)
 {
     LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
@@ -66,12 +73,7 @@ void CetonRecorder::run(void)
         recordingWait.wakeAll();
     }
 
-    // Make sure the first things in the file are a PAT & PMT
-    bool tmp = _wait_for_keyframe_option;
-    _wait_for_keyframe_option = false;
-    HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-    HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
-    _wait_for_keyframe_option = tmp;
+    StartNewFile();
 
     _stream_data->AddAVListener(this);
     _stream_data->AddWritingListener(this);
diff --git a/mythtv/libs/libmythtv/recorders/cetonrecorder.h b/mythtv/libs/libmythtv/recorders/cetonrecorder.h
index fe2d176..8233d46 100644
--- a/mythtv/libs/libmythtv/recorders/cetonrecorder.h
+++ b/mythtv/libs/libmythtv/recorders/cetonrecorder.h
@@ -26,6 +26,7 @@ class CetonRecorder : public DTVRecorder
 
     bool Open(void);
     void Close(void);
+    void StartNewFile(void);
 
     bool IsOpen(void) const { return _stream_handler; }
 
diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
index 60549f8..d619d9c 100644
--- a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
@@ -87,7 +87,12 @@ DTVRecorder::DTVRecorder(TVRec *rec) :
 {
     SetPositionMapType(MARK_GOP_BYFRAME);
     _payload_buffer.reserve(TSPacket::kSize * (50 + 1));
+
     ResetForNewFile();
+
+    memset(_stream_id,  0, sizeof(_stream_id));
+    memset(_pid_status, 0, sizeof(_pid_status));
+    memset(_continuity_counter, 0xff, sizeof(_continuity_counter));
 }
 
 DTVRecorder::~DTVRecorder()
@@ -147,14 +152,7 @@ void DTVRecorder::SetOptionsFromProfile(RecordingProfile *profile,
 void DTVRecorder::FinishRecording(void)
 {
     if (ringBuffer)
-    {
-        if (!_payload_buffer.empty())
-        {
-            ringBuffer->Write(&_payload_buffer[0], _payload_buffer.size());
-            _payload_buffer.clear();
-        }
         ringBuffer->WriterFlush();
-    }
 
     if (curRecording)
     {
@@ -171,7 +169,7 @@ void DTVRecorder::ResetForNewFile(void)
     LOG(VB_RECORD, LOG_INFO, LOC + "ResetForNewFile(void)");
     QMutexLocker locker(&positionMapLock);
 
-    // _first_keyframe, _seen_psp and m_h264_parser should
+    // _seen_psp and m_h264_parser should
     // not be reset here. This will only be called just as
     // we're seeing the first packet of a new keyframe for
     // writing to the new file and anything that makes the
@@ -180,7 +178,7 @@ void DTVRecorder::ResetForNewFile(void)
     // -- Daniel Kristjansson 2011-02-26
 
     _start_code                 = 0xffffffff;
-    //_first_keyframe
+    _first_keyframe             = -1;
     _has_written_other_keyframe = false;
     _last_keyframe_seen         = 0;
     _last_gop_seen              = 0;
@@ -191,20 +189,15 @@ void DTVRecorder::ResetForNewFile(void)
     //_recording
     _error                      = QString();
 
-    memset(_stream_id,  0, sizeof(_stream_id));
-    memset(_pid_status, 0, sizeof(_pid_status));
-    memset(_continuity_counter, 0xff, sizeof(_continuity_counter));
-
     _progressive_sequence       = 0;
     _repeat_pict                = 0;
 
-    _pes_synced                 = false;
+    //_pes_synced
     //_seen_sps
     positionMap.clear();
     positionMapDelta.clear();
     durationMap.clear();
     durationMapDelta.clear();
-    _payload_buffer.clear();
 
     locker.unlock();
     ClearStatistics();
@@ -215,9 +208,9 @@ void DTVRecorder::ClearStatistics(void)
     RecorderBase::ClearStatistics();
 
     memset(_ts_count, 0, sizeof(_ts_count));
-    for (int i = 0; i < 256; i++)
+    for (int i = 0; i < 256; ++i)
         _ts_last[i] = -1LL;
-    for (int i = 0; i < 256; i++)
+    for (int i = 0; i < 256; ++i)
         _ts_first[i] = -1LL;
     //_ts_first_dt -- doesn't need to be cleared only used if _ts_first>=0
     _packet_count.fetchAndStoreRelaxed(0);
@@ -274,58 +267,62 @@ void DTVRecorder::InitStreamData(void)
         _stream_data->SetDesiredProgram(_stream_data->DesiredProgram());
 }
 
-void DTVRecorder::BufferedWrite(const TSPacket &tspacket)
+void DTVRecorder::BufferedWrite(const TSPacket &tspacket, bool insert)
 {
-    // delay until first GOP to avoid decoder crash on res change
-    if (_wait_for_keyframe_option && _first_keyframe<0)
-        return;
-
-    if (curRecording && timeOfFirstDataIsSet.testAndSetRelaxed(0,1))
+    if (!insert) // PAT/PMT may need inserted in front of any buffered data
     {
-        QMutexLocker locker(&statisticsLock);
-        timeOfFirstData = MythDate::current();
-        timeOfLatestData = MythDate::current();
-        timeOfLatestDataTimer.start();
-    }
+        // delay until first GOP to avoid decoder crash on res change
+        if (!_buffer_packets && _wait_for_keyframe_option &&
+            _first_keyframe < 0)
+            return;
 
-    int val = timeOfLatestDataCount.fetchAndAddRelaxed(1);
-    int thresh = timeOfLatestDataPacketInterval.fetchAndAddRelaxed(0);
-    if (val > thresh)
-    {
-        QMutexLocker locker(&statisticsLock);
-        uint elapsed = timeOfLatestDataTimer.restart();
-        int interval = thresh;
-        if (elapsed > kTimeOfLatestDataIntervalTarget + 250)
-            interval = timeOfLatestDataPacketInterval
-                .fetchAndStoreRelaxed(thresh * 4 / 5);
-        else if (elapsed + 250 < kTimeOfLatestDataIntervalTarget)
-            interval = timeOfLatestDataPacketInterval
-                .fetchAndStoreRelaxed(thresh * 9 / 8);
-
-        timeOfLatestDataCount.fetchAndStoreRelaxed(1);
-        timeOfLatestData = MythDate::current();
-
-        LOG(VB_RECORD, LOG_DEBUG, LOC + QString("Updating timeOfLatestData ") +
-            QString("elapsed(%1) interval(%2)")
-            .arg(elapsed).arg(interval));
-    }
+        if (curRecording && timeOfFirstDataIsSet.testAndSetRelaxed(0,1))
+        {
+            QMutexLocker locker(&statisticsLock);
+            timeOfFirstData = MythDate::current();
+            timeOfLatestData = MythDate::current();
+            timeOfLatestDataTimer.start();
+        }
 
-    // Do we have to buffer the packet for exact keyframe detection?
-    if (_buffer_packets)
-    {
-        int idx = _payload_buffer.size();
-        _payload_buffer.resize(idx + TSPacket::kSize);
-        memcpy(&_payload_buffer[idx], tspacket.data(), TSPacket::kSize);
-        return;
-    }
+        int val = timeOfLatestDataCount.fetchAndAddRelaxed(1);
+        int thresh = timeOfLatestDataPacketInterval.fetchAndAddRelaxed(0);
+        if (val > thresh)
+        {
+            QMutexLocker locker(&statisticsLock);
+            uint elapsed = timeOfLatestDataTimer.restart();
+            int interval = thresh;
+            if (elapsed > kTimeOfLatestDataIntervalTarget + 250)
+                interval = timeOfLatestDataPacketInterval
+                           .fetchAndStoreRelaxed(thresh * 4 / 5);
+            else if (elapsed + 250 < kTimeOfLatestDataIntervalTarget)
+                interval = timeOfLatestDataPacketInterval
+                           .fetchAndStoreRelaxed(thresh * 9 / 8);
+
+            timeOfLatestDataCount.fetchAndStoreRelaxed(1);
+            timeOfLatestData = MythDate::current();
+
+            LOG(VB_RECORD, LOG_DEBUG, LOC +
+                QString("Updating timeOfLatestData elapsed(%1) interval(%2)")
+                .arg(elapsed).arg(interval));
+        }
 
-    // We are free to write the packet, but if we have buffered packet[s]
-    // we have to write them first...
-    if (!_payload_buffer.empty())
-    {
-        if (ringBuffer)
-            ringBuffer->Write(&_payload_buffer[0], _payload_buffer.size());
-        _payload_buffer.clear();
+        // Do we have to buffer the packet for exact keyframe detection?
+        if (_buffer_packets)
+        {
+            int idx = _payload_buffer.size();
+            _payload_buffer.resize(idx + TSPacket::kSize);
+            memcpy(&_payload_buffer[idx], tspacket.data(), TSPacket::kSize);
+            return;
+        }
+
+        // We are free to write the packet, but if we have buffered packet[s]
+        // we have to write them first...
+        if (!_payload_buffer.empty())
+        {
+            if (ringBuffer)
+                ringBuffer->Write(&_payload_buffer[0], _payload_buffer.size());
+            _payload_buffer.clear();
+        }
     }
 
     if (ringBuffer)
@@ -403,12 +400,11 @@ static const uint frameRateMap[16] = {
  */
 bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket)
 {
-    bool haveBufferedData = !_payload_buffer.empty();
     if (!tspacket->HasPayload()) // no payload to scan
-        return !haveBufferedData;
+        return _first_keyframe >= 0;
 
     if (!ringBuffer)
-        return !haveBufferedData;
+        return _first_keyframe >= 0;
 
     // if packet contains start of PES packet, start
     // looking for first byte of MPEG start code (3 bytes 0 0 1)
@@ -540,15 +536,36 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket)
 
     if (hasKeyFrame)
     {
+#if 0
+        LOG(VB_RECORD, LOG_ERR, LOC + QString
+            ("Keyframe @ %1 + %2 = %3")
+            .arg(ringBuffer->GetWritePosition())
+            .arg(_payload_buffer.size())
+            .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()));
+#endif
         _last_keyframe_seen = _frames_seen_count;
-        HandleKeyframe(_frames_written_count, TSPacket::kSize);
+        HandleKeyframe(0);
     }
 
     if (hasFrame)
     {
+#if 0
+        LOG(VB_RECORD, LOG_ERR, LOC + QString
+            ("Frame @ %1 + %2 = %3")
+            .arg(ringBuffer->GetWritePosition())
+            .arg(_payload_buffer.size())
+            .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()));
+#endif
+        _buffer_packets = false;  // We now know if it is a keyframe, or not
         _frames_seen_count++;
-        if (!_wait_for_keyframe_option || _first_keyframe>=0)
+        if (!_wait_for_keyframe_option || _first_keyframe >= 0)
             UpdateFramesWritten();
+        else
+        {
+            /* Found a frame that is not a keyframe, and we want to
+             * start on a keyframe */
+            _payload_buffer.clear();
+        }
     }
 
     if ((aspectRatio > 0) && (aspectRatio != m_videoAspect))
@@ -572,7 +589,7 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket)
         FrameRateChange(frameRate, _frames_written_count);
     }
 
-    return hasKeyFrame || (_payload_buffer.size() >= (188*50));
+    return _first_keyframe >= 0;
 }
 
 void DTVRecorder::HandleTimestamps(int stream_id, int64_t pts, int64_t dts)
@@ -680,7 +697,7 @@ bool DTVRecorder::FindAudioKeyframes(const TSPacket*)
         if (1 == (_frames_seen_count & 0x7))
         {
             _last_keyframe_seen = _frames_seen_count;
-            HandleKeyframe(_frames_written_count);
+            HandleKeyframe(_payload_buffer.size());
             hasKeyFrame = true;
         }
 
@@ -708,7 +725,7 @@ bool DTVRecorder::FindOtherKeyframes(const TSPacket *tspacket)
     UpdateFramesWritten();
     _last_keyframe_seen = _frames_seen_count;
 
-    HandleKeyframe(_frames_written_count);
+    HandleKeyframe(_payload_buffer.size());
 
     _has_written_other_keyframe = true;
 
@@ -719,24 +736,22 @@ bool DTVRecorder::FindOtherKeyframes(const TSPacket *tspacket)
  *  \brief This save the current frame to the position maps
  *         and handles ringbuffer switching.
  */
-void DTVRecorder::HandleKeyframe(uint64_t frameNum, int64_t extra)
+void DTVRecorder::HandleKeyframe(int64_t extra)
 {
     if (!ringBuffer)
         return;
 
-#if 0
-    unsigned long long frameNum = _frames_written_count;
-#endif
+    // Perform ringbuffer switch if needed.
+    CheckForRingBufferSwitch();
 
+    uint64_t frameNum = _frames_written_count;
     _first_keyframe = (_first_keyframe < 0) ? frameNum : _first_keyframe;
 
     // Add key frame to position map
     positionMapLock.lock();
     if (!positionMap.contains(frameNum))
     {
-        long long startpos = ringBuffer->GetWritePosition();
-        // FIXME: handle keyframes with start code spanning over two ts packets
-        startpos += _payload_buffer.size() - extra;
+        int64_t startpos = ringBuffer->GetWritePosition() + extra;
 
         // Don't put negative offsets into the database, they get munged into
         // MAX_INT64 - offset, which is an exceedingly large number, and
@@ -750,9 +765,6 @@ void DTVRecorder::HandleKeyframe(uint64_t frameNum, int64_t extra)
         }
     }
     positionMapLock.unlock();
-
-    // Perform ringbuffer switch if needed.
-    CheckForRingBufferSwitch();
 }
 
 /** \fn DTVRecorder::FindH264Keyframes(const TSPacket*)
@@ -762,16 +774,15 @@ void DTVRecorder::HandleKeyframe(uint64_t frameNum, int64_t extra)
  */
 bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
 {
+    if (!tspacket->HasPayload()) // no payload to scan
+        return _first_keyframe >= 0;
+
     if (!ringBuffer)
     {
         LOG(VB_GENERAL, LOG_ERR, LOC + "FindH264Keyframes: No ringbuffer");
-        return false;
+        return _first_keyframe >= 0;
     }
 
-    bool haveBufferedData = !_payload_buffer.empty();
-    if (!tspacket->HasPayload()) // no payload to scan
-        return !haveBufferedData;
-
     const bool payloadStart = tspacket->PayloadStart();
     if (payloadStart)
     {
@@ -790,7 +801,7 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
 
     // scan for PES packets and H.264 NAL units
     uint i = tspacket->AFCOffset();
-    for (; i < TSPacket::kSize; i++)
+    for (; i < TSPacket::kSize; ++i)
     {
         // special handling required when a new PES packet begins
         if (payloadStart && !_pes_synced)
@@ -858,10 +869,9 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
 
         // scan for a NAL unit start code
 
-        uint32_t bytes_used = m_h264_parser.addBytes(
-            tspacket->data() + i, TSPacket::kSize - i,
-            ringBuffer->GetWritePosition() + _payload_buffer.size()
-            );
+        uint32_t bytes_used = m_h264_parser.addBytes
+                              (tspacket->data() + i, TSPacket::kSize - i,
+                               ringBuffer->GetWritePosition());
         i += (bytes_used - 1);
 
         if (m_h264_parser.stateChanged())
@@ -879,19 +889,42 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
                 frameRate = m_h264_parser.frameRate();
             }
         }
-    } // for (; i < TSPacket::kSize; i++)
+    } // for (; i < TSPacket::kSize; ++i)
 
     if (hasKeyFrame)
     {
+#if 0
+        LOG(VB_RECORD, LOG_ERR, LOC + QString
+            ("Keyframe @ %1 + %2 = %3 AU %4")
+            .arg(ringBuffer->GetWritePosition())
+            .arg(_payload_buffer.size())
+            .arg(ringBuffer->GetWritePosition() + _payload_buffer.size())
+            .arg(m_h264_parser.keyframeAUstreamOffset()));
+#endif
         _last_keyframe_seen = _frames_seen_count;
         HandleH264Keyframe();
     }
 
     if (hasFrame)
     {
+#if 0
+        LOG(VB_RECORD, LOG_ERR, LOC + QString
+            ("Frame @ %1 + %2 = %3 AU %4")
+            .arg(ringBuffer->GetWritePosition())
+            .arg(_payload_buffer.size())
+            .arg(ringBuffer->GetWritePosition() + _payload_buffer.size())
+            .arg(m_h264_parser.keyframeAUstreamOffset()));
+#endif
+        _buffer_packets = false;  // We now know if this is a keyframe
         _frames_seen_count++;
         if (!_wait_for_keyframe_option || _first_keyframe >= 0)
             UpdateFramesWritten();
+        else
+        {
+            /* Found a frame that is not a keyframe, and we want to
+             * start on a keyframe */
+            _payload_buffer.clear();
+        }
     }
 
     if ((aspectRatio > 0) && (aspectRatio != m_videoAspect))
@@ -909,7 +942,6 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
 
     if (frameRate != 0 && frameRate != m_frameRate)
     {
-
         LOG(VB_RECORD, LOG_INFO, LOC +
             QString("FindH264Keyframes: timescale: %1, tick: %2, framerate: %3")
                       .arg( m_h264_parser.GetTimeScale() )
@@ -919,7 +951,7 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
         FrameRateChange(frameRate, _frames_written_count);
     }
 
-    return hasKeyFrame || (_payload_buffer.size() >= (188*50));
+    return _seen_sps;
 }
 
 /** \fn DTVRecorder::HandleH264Keyframe(void)
@@ -928,23 +960,30 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
  */
 void DTVRecorder::HandleH264Keyframe(void)
 {
-    unsigned long long frameNum = _frames_written_count;
+    // Perform ringbuffer switch if needed.
+    CheckForRingBufferSwitch();
 
-    _first_keyframe = (_first_keyframe < 0) ? frameNum : _first_keyframe;
+    uint64_t startpos;
+    uint64_t frameNum = _frames_written_count;
+
+    if (_first_keyframe < 0)
+    {
+        _first_keyframe = frameNum;
+        startpos = 0;
+    }
+    else
+        startpos = m_h264_parser.keyframeAUstreamOffset();
 
     // Add key frame to position map
     positionMapLock.lock();
     if (!positionMap.contains(frameNum))
     {
-        positionMapDelta[frameNum] = m_h264_parser.keyframeAUstreamOffset();
-        positionMap[frameNum]      = m_h264_parser.keyframeAUstreamOffset();
+        positionMapDelta[frameNum] = startpos;
+        positionMap[frameNum]      = startpos;
         durationMap[frameNum]      = _total_duration / 1000;
         durationMapDelta[frameNum] = _total_duration / 1000;
     }
     positionMapLock.unlock();
-
-    // Perform ringbuffer switch if needed.
-    CheckForRingBufferSwitch();
 }
 
 void DTVRecorder::FindPSKeyFrames(const uint8_t *buffer, uint len)
@@ -1065,7 +1104,7 @@ void DTVRecorder::FindPSKeyFrames(const uint8_t *buffer, uint len)
         if (hasKeyFrame)
         {
             _last_keyframe_seen = _frames_seen_count;
-            HandleKeyframe(_frames_written_count, bufptr - bufstart);
+            HandleKeyframe(_payload_buffer.size() - (bufptr - bufstart));
         }
 
         if ((aspectRatio > 0) && (aspectRatio != m_videoAspect))
@@ -1149,8 +1188,9 @@ void DTVRecorder::HandlePAT(const ProgramAssociationTable *_pat)
 
     if (!pmtpid)
     {
-        LOG(VB_RECORD, LOG_ERR, LOC + "SetPAT(): "
-            "Ignoring PAT not containing our desired program...");
+        LOG(VB_RECORD, LOG_ERR, LOC +
+            QString("SetPAT(): Ignoring PAT not containing our desired "
+                    "program (%1)...").arg(progNum));
         return;
     }
 
@@ -1162,7 +1202,7 @@ void DTVRecorder::HandlePAT(const ProgramAssociationTable *_pat)
     delete oldpat;
 
     // Listen for the other PMTs for faster channel switching
-    for (uint i = 0; _input_pat && (i < _input_pat->ProgramCount()); i++)
+    for (uint i = 0; _input_pat && (i < _input_pat->ProgramCount()); ++i)
     {
         uint pmt_pid = _input_pat->ProgramPID(i);
         if (!_stream_data->IsListeningPID(pmt_pid))
@@ -1183,7 +1223,7 @@ void DTVRecorder::HandlePMT(uint progNum, const ProgramMapTable *_pmt)
         QString sistandard = GetSIStandard();
 
         bool has_no_av = true;
-        for (uint i = 0; i < _input_pmt->StreamCount() && has_no_av; i++)
+        for (uint i = 0; i < _input_pmt->StreamCount() && has_no_av; ++i)
         {
             has_no_av &= !_input_pmt->IsVideo(i, sistandard);
             has_no_av &= !_input_pmt->IsAudio(i, sistandard);
@@ -1195,7 +1235,8 @@ void DTVRecorder::HandlePMT(uint progNum, const ProgramMapTable *_pmt)
     }
 }
 
-void DTVRecorder::HandleSingleProgramPAT(ProgramAssociationTable *pat)
+void DTVRecorder::HandleSingleProgramPAT(ProgramAssociationTable *pat,
+                                         bool insert)
 {
     if (!pat)
     {
@@ -1210,11 +1251,11 @@ void DTVRecorder::HandleSingleProgramPAT(ProgramAssociationTable *pat)
     pat->tsheader()->SetContinuityCounter(next_cc);
     pat->GetAsTSPackets(_scratch, next_cc);
 
-    for (uint i = 0; i < _scratch.size(); i++)
-        DTVRecorder::BufferedWrite(_scratch[i]);
+    for (uint i = 0; i < _scratch.size(); ++i)
+        DTVRecorder::BufferedWrite(_scratch[i], insert);
 }
 
-void DTVRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
+void DTVRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert)
 {
     if (!pmt)
     {
@@ -1223,7 +1264,7 @@ void DTVRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
     }
 
     // collect stream types for H.264 (MPEG-4 AVC) keyframe detection
-    for (uint i = 0; i < pmt->StreamCount(); i++)
+    for (uint i = 0; i < pmt->StreamCount(); ++i)
         _stream_id[pmt->StreamPID(i)] = pmt->StreamType(i);
 
     if (!ringBuffer)
@@ -1233,8 +1274,8 @@ void DTVRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt)
     pmt->tsheader()->SetContinuityCounter(next_cc);
     pmt->GetAsTSPackets(_scratch, next_cc);
 
-    for (uint i = 0; i < _scratch.size(); i++)
-        DTVRecorder::BufferedWrite(_scratch[i]);
+    for (uint i = 0; i < _scratch.size(); ++i)
+        DTVRecorder::BufferedWrite(_scratch[i], insert);
 }
 
 bool DTVRecorder::ProcessTSPacket(const TSPacket &tspacket)
@@ -1260,7 +1301,8 @@ bool DTVRecorder::ProcessTSPacket(const TSPacket &tspacket)
     // Only create fake keyframe[s] if there are no audio/video streams
     if (_input_pmt && _has_no_av)
     {
-        _buffer_packets = !FindOtherKeyframes(&tspacket);
+        FindOtherKeyframes(&tspacket);
+        _buffer_packets = false;
     }
     else
     {
@@ -1284,17 +1326,27 @@ bool DTVRecorder::ProcessVideoTSPacket(const TSPacket &tspacket)
 
     uint streamType = _stream_id[tspacket.PID()];
 
-    // Check for keyframes and count frames
-    if (streamType == StreamID::H264Video)
+    if (tspacket.HasPayload() && tspacket.PayloadStart())
     {
-        _buffer_packets = !FindH264Keyframes(&tspacket);
-        if (_wait_for_keyframe_option && !_seen_sps)
-            return true;
+        // buffer packets until we know if this is a keyframe
+        _buffer_packets = true;
+#if 0
+        LOG(VB_RECORD, LOG_ERR, LOC + QString
+            ("ProcessVideoTSPacket PayloadStart @ %1 + %2 = %3")
+            .arg(ringBuffer->GetWritePosition())
+            .arg(_payload_buffer.size())
+            .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()));
+#endif
     }
+
+    // Check for keyframes and count frames
+    if (streamType == StreamID::H264Video)
+        FindH264Keyframes(&tspacket);
+    else if (streamType != 0)
+        FindMPEG2Keyframes(&tspacket);
     else
-    {
-        _buffer_packets = !FindMPEG2Keyframes(&tspacket);
-    }
+        LOG(VB_RECORD, LOG_ERR, LOC +
+            "ProcessVideoTSPacket: unknown stream type!");
 
     return ProcessAVTSPacket(tspacket);
 }
@@ -1304,13 +1356,30 @@ bool DTVRecorder::ProcessAudioTSPacket(const TSPacket &tspacket)
     if (!ringBuffer)
         return true;
 
-    _buffer_packets = !FindAudioKeyframes(&tspacket);
+    if (tspacket.HasPayload() && tspacket.PayloadStart())
+    {
+        // buffer packets until we know if this is a keyframe
+        _buffer_packets = true;
+#if 0
+        LOG(VB_RECORD, LOG_ERR, LOC + QString
+            ("ProcessAudioTSPacket PayloadStart @ %1 + %2 = %3")
+            .arg(ringBuffer->GetWritePosition())
+            .arg(_payload_buffer.size())
+            .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()));
+#endif
+    }
+
+    FindAudioKeyframes(&tspacket);
     return ProcessAVTSPacket(tspacket);
 }
 
 /// Common code for processing either audio or video packets
 bool DTVRecorder::ProcessAVTSPacket(const TSPacket &tspacket)
 {
+    // Sync recording start to first keyframe
+    if (!_buffer_packets && _wait_for_keyframe_option && _first_keyframe < 0)
+        return true;
+
     const uint pid = tspacket.PID();
 
     if (pid != 0x1fff)
@@ -1328,10 +1397,6 @@ bool DTVRecorder::ProcessAVTSPacket(const TSPacket &tspacket)
                 .arg(erate,5,'f',2));
     }
 
-    // Sync recording start to first keyframe
-    if (_wait_for_keyframe_option && _first_keyframe < 0)
-        return true;
-
     // Sync streams to the first Payload Unit Start Indicator
     // _after_ first keyframe iff _wait_for_keyframe_option is true
     if (!(_pid_status[pid] & kPayloadStartSeen) && tspacket.HasPayload())
diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.h b/mythtv/libs/libmythtv/recorders/dtvrecorder.h
index 6617366..70d287c 100644
--- a/mythtv/libs/libmythtv/recorders/dtvrecorder.h
+++ b/mythtv/libs/libmythtv/recorders/dtvrecorder.h
@@ -64,8 +64,8 @@ class DTVRecorder :
     void HandleEncryptionStatus(uint /*pnum*/, bool /*encrypted*/) { }
 
     // MPEG Single Program Stream Listener
-    void HandleSingleProgramPAT(ProgramAssociationTable *pat);
-    void HandleSingleProgramPMT(ProgramMapTable *pmt);
+    void HandleSingleProgramPAT(ProgramAssociationTable *pat, bool insert);
+    void HandleSingleProgramPMT(ProgramMapTable *pmt, bool insert);
 
     // ATSC Main
     void HandleSTT(const SystemTimeTable*) { UpdateCAMTimeOffset(); }
@@ -93,11 +93,11 @@ class DTVRecorder :
     void FinishRecording(void);
     void ResetForNewFile(void);
 
-    void HandleKeyframe(uint64_t frameNum, int64_t extra = 0);
+    void HandleKeyframe(int64_t extra);
     void HandleTimestamps(int stream_id, int64_t pts, int64_t dts);
     void UpdateFramesWritten(void);
 
-    void BufferedWrite(const TSPacket &tspacket);
+    void BufferedWrite(const TSPacket &tspacket, bool insert = false);
 
     // MPEG TS "audio only" support
     bool FindAudioKeyframes(const TSPacket *tspacket);
diff --git a/mythtv/libs/libmythtv/recorders/dvbrecorder.cpp b/mythtv/libs/libmythtv/recorders/dvbrecorder.cpp
index 9aba52f..e0ea31f 100644
--- a/mythtv/libs/libmythtv/recorders/dvbrecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/dvbrecorder.cpp
@@ -72,6 +72,13 @@ void DVBRecorder::Close(void)
     LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
 }
 
+void DVBRecorder::StartNewFile(void)
+{
+    // Make sure the first things in the file are a PAT & PMT
+    HandleSingleProgramPAT(_stream_data->PATSingleProgram(), true);
+    HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), true);
+}
+
 void DVBRecorder::run(void)
 {
     if (!Open())
@@ -92,12 +99,7 @@ void DVBRecorder::run(void)
     if (_channel && (_channel->GetSIStandard() == "dvb"))
         _stream_data->AddListeningPID(DVB_TDT_PID);
 
-    // Make sure the first things in the file are a PAT & PMT
-    bool tmp = _wait_for_keyframe_option;
-    _wait_for_keyframe_option = false;
-    HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-    HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
-    _wait_for_keyframe_option = tmp;
+    StartNewFile();
 
     _stream_data->AddAVListener(this);
     _stream_data->AddWritingListener(this);
diff --git a/mythtv/libs/libmythtv/recorders/dvbrecorder.h b/mythtv/libs/libmythtv/recorders/dvbrecorder.h
index eb0b5f8..e82c2fe 100644
--- a/mythtv/libs/libmythtv/recorders/dvbrecorder.h
+++ b/mythtv/libs/libmythtv/recorders/dvbrecorder.h
@@ -28,6 +28,7 @@ class DVBRecorder : public DTVRecorder
     bool Open(void);
     bool IsOpen(void) const;
     void Close(void);
+    void StartNewFile(void);
 
   private:
     bool PauseAndWait(int timeout = 100);
diff --git a/mythtv/libs/libmythtv/recorders/hdhrrecorder.cpp b/mythtv/libs/libmythtv/recorders/hdhrrecorder.cpp
index 363d373..b98495e 100644
--- a/mythtv/libs/libmythtv/recorders/hdhrrecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/hdhrrecorder.cpp
@@ -48,6 +48,13 @@ void HDHRRecorder::Close(void)
     LOG(VB_RECORD, LOG_INFO, LOC + "Close() -- end");
 }
 
+void HDHRRecorder::StartNewFile(void)
+{
+    // Make sure the first things in the file are a PAT & PMT
+    HandleSingleProgramPAT(_stream_data->PATSingleProgram(), true);
+    HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), true);
+}
+
 void HDHRRecorder::run(void)
 {
     LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
@@ -67,12 +74,7 @@ void HDHRRecorder::run(void)
         recordingWait.wakeAll();
     }
 
-    // Make sure the first things in the file are a PAT & PMT
-    bool tmp = _wait_for_keyframe_option;
-    _wait_for_keyframe_option = false;
-    HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-    HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
-    _wait_for_keyframe_option = tmp;
+    StartNewFile();
 
     _stream_data->AddAVListener(this);
     _stream_data->AddWritingListener(this);
diff --git a/mythtv/libs/libmythtv/recorders/hdhrrecorder.h b/mythtv/libs/libmythtv/recorders/hdhrrecorder.h
index 44b3fc1..7523e37 100644
--- a/mythtv/libs/libmythtv/recorders/hdhrrecorder.h
+++ b/mythtv/libs/libmythtv/recorders/hdhrrecorder.h
@@ -26,6 +26,7 @@ class HDHRRecorder : public DTVRecorder
     bool Open(void);
     bool IsOpen(void) const { return _stream_handler; }
     void Close(void);
+    void StartNewFile(void);
 
     QString GetSIStandard(void) const;
 
diff --git a/mythtv/libs/libmythtv/recorders/iptvrecorder.cpp b/mythtv/libs/libmythtv/recorders/iptvrecorder.cpp
index 39a35b1..3d081bc 100644
--- a/mythtv/libs/libmythtv/recorders/iptvrecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/iptvrecorder.cpp
@@ -91,6 +91,13 @@ bool IPTVRecorder::PauseAndWait(int timeout)
     return IsPaused(true);
 }
 
+void IPTVRecorder::StartNewFile(void)
+{
+    // Make sure the first things in the file are a PAT & PMT
+    HandleSingleProgramPAT(_stream_data->PATSingleProgram(), true);
+    HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), true);
+}
+
 void IPTVRecorder::run(void)
 {
     LOG(VB_RECORD, LOG_INFO, LOC + "run -- begin");
@@ -109,12 +116,7 @@ void IPTVRecorder::run(void)
         recordingWait.wakeAll();
     }
 
-    // Make sure the first things in the file are a PAT & PMT
-    bool tmp = _wait_for_keyframe_option;
-    _wait_for_keyframe_option = false;
-    HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-    HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
-    _wait_for_keyframe_option = tmp;
+    StartNewFile();
 
     _stream_data->AddAVListener(this);
     _stream_data->AddWritingListener(this);
diff --git a/mythtv/libs/libmythtv/recorders/iptvrecorder.h b/mythtv/libs/libmythtv/recorders/iptvrecorder.h
index d68c1e6..cbcd041 100644
--- a/mythtv/libs/libmythtv/recorders/iptvrecorder.h
+++ b/mythtv/libs/libmythtv/recorders/iptvrecorder.h
@@ -24,6 +24,7 @@ class IPTVRecorder : public DTVRecorder
     virtual bool Open(void); // RecorderBase
     virtual void Close(void); // RecorderBase
     bool IsOpen(void) const;
+    void StartNewFile(void);
 
     virtual void SetStreamData(MPEGStreamData*); // DTVRecorder
     virtual bool PauseAndWait(int timeout = 100); // RecorderBase
diff --git a/mythtv/libs/libmythtv/recorders/mpegrecorder.cpp b/mythtv/libs/libmythtv/recorders/mpegrecorder.cpp
index 1a5aee0..ffb6642 100644
--- a/mythtv/libs/libmythtv/recorders/mpegrecorder.cpp
+++ b/mythtv/libs/libmythtv/recorders/mpegrecorder.cpp
@@ -932,9 +932,8 @@ void MpegRecorder::run(void)
         _stream_data->AddWritingListener(this);
 
         // Make sure the first things in the file are a PAT & PMT
-        _wait_for_keyframe_option = false;
-        HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-        HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
+        HandleSingleProgramPAT(_stream_data->PATSingleProgram(), true);
+        HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), true);
         _wait_for_keyframe_option = true;
     }
 
@@ -1253,8 +1252,8 @@ void MpegRecorder::RestartEncoding(void)
         _stream_data->PMTSingleProgram())
     {
         _wait_for_keyframe_option = false;
-        HandleSingleProgramPAT(_stream_data->PATSingleProgram());
-        HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
+        HandleSingleProgramPAT(_stream_data->PATSingleProgram(), false);
+        HandleSingleProgramPMT(_stream_data->PMTSingleProgram(), false);
     }
 
     if (driver == "hdpvr") // HD-PVR will sometimes reset to defaults
