Index: libs/libmythtv/dtvrecorder.h
===================================================================
--- libs/libmythtv/dtvrecorder.h	(revision 17759)
+++ libs/libmythtv/dtvrecorder.h	(working copy)
@@ -51,7 +51,7 @@
     void FinishRecording(void);
     void ResetForNewFile(void);
 
-    void HandleKeyframe();
+    void HandleKeyframe(uint64_t extra = 0);
 
     void BufferedWrite(const TSPacket &tspacket);
 
@@ -66,8 +66,7 @@
     void HandleH264Keyframe(void);
 
     // MPEG2 PS support (Hauppauge PVR-x50/PVR-500)
-    void HandlePSKeyframe(void);
-    bool FindPSKeyFrames(unsigned char *buffer, int len);
+    void FindPSKeyFrames(const uint8_t *buffer, uint len);
 
     // For handling other (non audio/video) packets
     bool FindOtherKeyframes(const TSPacket *tspacket);
@@ -97,9 +96,6 @@
 
     bool _has_written_other_keyframe;
 
-    /// Used for PVR-150/250/500 which have a fixed keyframe distance of 12 or 15
-    int _keyframedist;
-
     // state tracking variables
     /// True iff recording is actually being performed
     bool _recording;
Index: libs/libmythtv/dtvrecorder.cpp
===================================================================
--- libs/libmythtv/dtvrecorder.cpp	(revision 17759)
+++ libs/libmythtv/dtvrecorder.cpp	(working copy)
@@ -46,7 +46,6 @@
     _request_recording(false),
     _wait_for_keyframe_option(true),
     _has_written_other_keyframe(false),
-    _keyframedist(15),
     // state
     _recording(false),
     _error(false),
@@ -396,11 +395,11 @@
     nextRingBufferLock.unlock();
 }
 
-/** \fn DTVRecorder::HandleKeyframe(void)
+/** \fn DTVRecorder::HandleKeyframe(uint64_t)
  *  \brief This save the current frame to the position maps
  *         and handles ringbuffer switching.
  */
-void DTVRecorder::HandleKeyframe(void)
+void DTVRecorder::HandleKeyframe(uint64_t extra)
 {
     if (!ringBuffer)
         return;
@@ -415,7 +414,7 @@
     {
         long long startpos = ringBuffer->GetWritePosition();
         // FIXME: handle keyframes with start code spanning over two ts packets
-        startpos += _payload_buffer.size();
+        startpos += _payload_buffer.size() + extra;
         positionMapDelta[frameNum] = startpos;
         positionMap[frameNum]      = startpos;
     }
@@ -577,108 +576,92 @@
     CheckForRingBufferSwitch();
 }
 
-/** \fn DTVRecorder::HandlePSKeyframe(void)
- *  \brief This save the current frame to the position maps
- *         and handles ringbuffer switching.
- */
-void DTVRecorder::HandlePSKeyframe(void)
+void DTVRecorder::FindPSKeyFrames(const uint8_t *buffer, uint len)
 {
-    if (!ringBuffer)
-        return;
+    const uint maxKFD = kMaxKeyFrameDistance;
 
-    unsigned long long frameNum = _last_gop_seen;
+    const uint8_t *bufstart = buffer;
+    const uint8_t *bufptr   = buffer;
+    const uint8_t *bufend   = buffer + len;
 
-    _first_keyframe = (_first_keyframe < 0) ? frameNum : _first_keyframe;
-
-    // Add key frame to position map
-    positionMapLock.lock();
-    if (!positionMap.contains(frameNum))
+    while (bufptr < bufend)
     {
-        long long startpos = ringBuffer->GetWritePosition();
-        // FIXME: handle keyframes with start code spanning over two ts packets
-        startpos += _payload_buffer.size();
-        positionMapDelta[frameNum] = startpos;
-        positionMap[frameNum]      = startpos;
-    }
-    positionMapLock.unlock();
+        bool hasFrame     = false;
+        bool hasKeyFrame  = false;
 
-    // Perform ringbuffer switch if needed.
-    CheckForRingBufferSwitch();
-}
+        bufptr = ff_find_start_code(bufptr, bufend, &_start_code);
+        if ((_start_code & 0xffffff00) != 0x00000100)
+            continue;
 
+        const int stream_id = _start_code & 0x000000ff;
+        if (PESStreamID::PictureStartCode == stream_id)
+        {
+            hasFrame = true;
+        }
+        else if (PESStreamID::GOPStartCode == stream_id)
+        {
+            _last_gop_seen  = _frames_seen_count;
+            hasKeyFrame    |= true;
+        }
+        else if (PESStreamID::SequenceStartCode == stream_id)
+        {
+            _last_seq_seen  = _frames_seen_count;
+            hasKeyFrame    |= (_last_gop_seen + maxKFD)<_frames_seen_count;
+        }
+        else if (PESStreamID::PackHeader == stream_id)
+        {
+            _start_code = 0xffffffff;
+        }
 
-bool DTVRecorder::FindPSKeyFrames(unsigned char *buffer, int len)
-{
-    unsigned char *bufptr = buffer, *bufstart = buffer;
-    uint v = 0;
-    int leftlen = len;
-    bool hasKeyFrame = false;
+        if (hasFrame && !hasKeyFrame)
+        {
+            // If we have seen kMaxKeyFrameDistance frames since the
+            // last GOP or SEQ stream_id, then pretend this picture
+            // is a keyframe. We may get artifacts but at least
+            // we will be able to skip frames.
+            hasKeyFrame = !(_frames_seen_count & 0xf);
+            hasKeyFrame &= (_last_gop_seen + maxKFD) < _frames_seen_count;
+            hasKeyFrame &= (_last_seq_seen + maxKFD) < _frames_seen_count;
+        }
 
-    while (bufptr < buffer + len)
-    {
-        v = *bufptr++;
-        if (_start_code == 0x000001)
+        if (hasKeyFrame)
         {
-            _start_code = ((_start_code << 8) | v) & 0xFFFFFF;
-            const int stream_id = _start_code & 0x000000ff;
+            _last_keyframe_seen = _frames_seen_count;
+            HandleKeyframe(bufstart - bufptr);
+        }
 
-            if (stream_id == PESStreamID::PackHeader)
-            {
-                _last_keyframe_seen = ringBuffer->GetWritePosition() +
-                                      _payload_buffer.size();
+        if (hasFrame)
+        {
+            _frames_seen_count++;
+            if (!_wait_for_keyframe_option || _first_keyframe>=0)
+                _frames_written_count++;
+        }
 
-                int curpos = bufptr - bufstart - 4;
-                if (curpos < 0)
+        if (hasKeyFrame || hasFrame)
+        {
+            // 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)
                 {
-                    // header was split
-                    if (_payload_buffer.size() + curpos > 0)
-                        ringBuffer->Write(&_payload_buffer[0],
-                                          _payload_buffer.size() + curpos);
-
-                    _payload_buffer.resize(4);
-                    memcpy(&_payload_buffer[0], &_start_code, 4);
-
-                    leftlen = leftlen - curpos + 4;
-                    bufstart = bufptr;
+                    ringBuffer->Write(
+                        &_payload_buffer[0], _payload_buffer.size());
                 }
-                else
-                {
-                    // header was entirely in this packet
-                    int idx = _payload_buffer.size();
-                    _payload_buffer.resize(idx + curpos);
-                    memcpy(&_payload_buffer[idx], bufstart, curpos);
+                _payload_buffer.clear();
+            }
 
-                    bufstart += curpos;
-                    leftlen -= curpos;
+            if (ringBuffer)
+                ringBuffer->Write(bufstart, (bufptr - bufstart));
 
-                    if (_payload_buffer.size() > 0)
-                        ringBuffer->Write(&_payload_buffer[0],
-                                          _payload_buffer.size());
-                    _payload_buffer.clear();
-                }
-                _frames_seen_count++;
-            }
-            else if (stream_id == PESStreamID::SequenceStartCode)
-            {
-                _last_seq_seen = _last_keyframe_seen;
-            }
-            else if (stream_id == PESStreamID::GOPStartCode &&
-                     _last_seq_seen == _last_keyframe_seen)
-            {
-                _frames_written_count = _last_gop_seen * _keyframedist;
-                _last_gop_seen++;
-                HandlePSKeyframe();
-            }
+            bufstart = bufptr;
         }
-        else
-            _start_code = ((_start_code << 8) | v) & 0xFFFFFF;
     }
 
-    int idx = _payload_buffer.size();
-    _payload_buffer.resize(idx + leftlen);
-    memcpy(&_payload_buffer[idx], bufstart, leftlen);
-
-    return hasKeyFrame;
+    uint64_t idx = _payload_buffer.size();
+    uint64_t rem = (bufend - bufstart);
+    _payload_buffer.resize(idx + rem);
+    memcpy(&_payload_buffer[idx], bufstart, rem);
 }
 
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: libs/libmythtv/mpegrecorder.cpp
===================================================================
--- libs/libmythtv/mpegrecorder.cpp	(revision 17759)
+++ libs/libmythtv/mpegrecorder.cpp	(working copy)
@@ -98,7 +98,6 @@
     // TS packet handling
     _stream_data(NULL)                                   
 {
-    SetPositionMapType(MARK_GOP_START);
 }
 
 MpegRecorder::~MpegRecorder()
@@ -606,8 +605,6 @@
         return false;
     }
 
-    _keyframedist = (ivtvcodec.framerate) ? 12 : _keyframedist;
-
     return true;
 }
 
@@ -706,32 +703,6 @@
         }
     }
 
-    if (driver != "hdpvr")
-    {
-        // Get GOP size in frames
-        struct v4l2_ext_control ext_ctrl;
-        struct v4l2_ext_controls ctrls;
-
-        bzero(&ext_ctrl, sizeof(struct v4l2_ext_control));
-        bzero(&ctrls, sizeof(struct v4l2_ext_controls));
-
-        ext_ctrl.id    = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
-        ext_ctrl.value = 0;
-
-        ctrls.ctrl_class  = V4L2_CTRL_CLASS_MPEG;
-        ctrls.count       = 1;
-        ctrls.controls    = &ext_ctrl;
-
-        if (ioctl(chanfd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0)
-        {
-            VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get "
-                    "V4L2_CID_MPEG_VIDEO_GOP_SIZE, defaulting to 12" + ENO);
-            ext_ctrl.value = 12;
-        }
-
-        _keyframedist = ext_ctrl.value;
-    }
-
     return true;
 }
 
@@ -875,8 +846,6 @@
 
     if (driver == "hdpvr")
     {
-        SetPositionMapType(MARK_GOP_BYFRAME);
-
         int progNum = 1;
         MPEGStreamData *sd = new MPEGStreamData(progNum, true);
         sd->SetRecordingType(_recording_type);
@@ -891,10 +860,6 @@
         HandleSingleProgramPMT(_stream_data->PMTSingleProgram());
         _wait_for_keyframe_option = true;
     }
-    else
-    {
-        SetPositionMapType(MARK_GOP_START);
-    }
 
     encoding = true;
     recording = true;
@@ -1147,8 +1112,7 @@
 
     if (curRecording)
     {
-        curRecording->ClearPositionMap(
-            (driver == "hdpvr") ? MARK_GOP_BYFRAME : MARK_GOP_START);
+        curRecording->ClearPositionMap(MARK_GOP_BYFRAME);
     }
     if (_stream_data)
         _stream_data->Reset(_stream_data->DesiredProgram());
