--- /home/mythtv/work2/mythtv-0.19/libs/libmythtv/dtvrecorder.h	2005-12-14 07:54:48.000000000 -0800
+++ libs/libmythtv/dtvrecorder.h	2006-02-20 18:22:59.000000000 -0800
@@ -59,6 +59,7 @@
     // used for scanning pes headers for keyframes
     uint      _header_pos;
     int       _first_keyframe;
+    int       _position_within_gop_header;
     unsigned long long _last_gop_seen;
     unsigned long long _last_seq_seen;
     unsigned long long _last_keyframe_seen;
--- /home/mythtv/work2/mythtv-0.19/libs/libmythtv/dtvrecorder.cpp	2006-02-07 13:56:06.000000000 -0800
+++ libs/libmythtv/dtvrecorder.cpp	2006-02-20 18:49:09.000000000 -0800
@@ -37,6 +37,7 @@
     _stream_fd(-1),
     // used for scanning pes headers for keyframes
     _header_pos(0),                 _first_keyframe(-1),
+    _position_within_gop_header(0),
     _last_gop_seen(0),              _last_seq_seen(0),
     _last_keyframe_seen(0),
     // settings
@@ -126,6 +127,7 @@
 
     _header_pos                 = 0;
     _first_keyframe             =-1;
+    _position_within_gop_header = 0;
     _last_keyframe_seen         = 0;
     _last_gop_seen              = 0;
     _last_seq_seen              = 0;
@@ -195,6 +197,101 @@
  */
 bool DTVRecorder::FindKeyframes(const TSPacket* tspacket)
 {
+#define AVG_KEYFRAME_DIFF 16
+#define MAX_KEYFRAME_DIFF 32
+#define DEBUG_FIND_KEY_FRAMES 0 /* set to 1 to debug */
+    bool haveBufferedData = !_payload_buffer.empty(); 
+    bool hasKeyFrame = false;
+    bool noPayload = !tspacket->HasPayload();
+    bool payloadStart = tspacket->PayloadStart();
+
+    if (noPayload)
+        return !haveBufferedData; // no payload to scan
+
+    if (payloadStart)
+    { // packet contains start of PES packet
+        _position_within_gop_header = 0; // start looking for first byte of pattern
+    }
+
+    // Scan for PES header codes; specifically picture_start
+    // and group_start (of_pictures).  These should be within
+    // this first TS packet of the PES packet.
+    //   00 00 01 00: picture_start_code
+    //   00 00 01 B8: group_start_code
+    //   00 00 01 B3: seq_start_code
+    //   (there are others that we don't care about)
+    long long frameSeenNum = _frames_seen_count;
+    const unsigned char *buffer = tspacket->data();
+    for (unsigned int i = tspacket->AFCOffset(); i+1<TSPacket::SIZE; i++)
+    {
+        const unsigned char k = buffer[i];
+        if (0 == _position_within_gop_header)
+            _position_within_gop_header = (k == 0x00) ? 1 : 0;
+        else if (1 == _position_within_gop_header)
+            _position_within_gop_header = (k == 0x00) ? 2 : 0;
+        else 
+        {
+            if (0x01 != k)
+            {
+                _position_within_gop_header = (k == 0x00) ? 2 : 0;
+                continue;
+            }
+            const unsigned char k1 = buffer[i+1];
+            if (0x00 == k1)
+            {   //   00 00 01 00: picture_start_code
+                _frames_written_count += (_first_keyframe > 0) ? 1 : 0;
+                _frames_seen_count++;
+                // We've seen 30 frames and no GOP or seq header? let's pretend we have them
+                if ((0==(_frames_seen_count & 0xf)) &&
+                    (_last_gop_seen+(MAX_KEYFRAME_DIFF+AVG_KEYFRAME_DIFF))<frameSeenNum &&
+                    (_last_seq_seen+(MAX_KEYFRAME_DIFF+AVG_KEYFRAME_DIFF))<frameSeenNum) {
+#if DEBUG_FIND_KEY_FRAMES
+                    VERBOSE(VB_RECORD, QString("f16 sc(%1) wc(%2) lgop(%3) lseq(%4)").
+                            arg(_frames_seen_count).arg(_frames_written_count).
+                            arg(_last_gop_seen).arg(_last_seq_seen));
+#endif
+                    HandleKeyframe();
+		    hasKeyFrame = true;
+                    _last_keyframe_seen = frameSeenNum;
+                }
+            } else if (0xB8 == k1)
+            {   //   00 00 01 B8: group_start_code
+#if DEBUG_FIND_KEY_FRAMES
+                VERBOSE(VB_RECORD, QString("GOP sc(%1) wc(%2) lgop(%3) lseq(%4)").
+                        arg(_frames_seen_count).arg(_frames_written_count).
+                        arg(_last_gop_seen).arg(_last_seq_seen));
+#endif
+                HandleKeyframe();
+		hasKeyFrame = true;
+                _last_keyframe_seen = _last_gop_seen = frameSeenNum;
+            } else if (0xB3 == k1)
+            {   //   00 00 01 B3: seq_start_code
+                if ((_last_gop_seen+MAX_KEYFRAME_DIFF)<frameSeenNum)
+                {
+#if DEBUG_FIND_KEY_FRAMES
+                    VERBOSE(VB_RECORD, QString("seq sc(%1) wc(%2) lgop(%3) lseq(%4)").
+                        arg(_frames_seen_count).arg(_frames_written_count).
+                        arg(_last_gop_seen).arg(_last_seq_seen));
+#endif
+                    HandleKeyframe();
+		    hasKeyFrame = true;
+                    _last_keyframe_seen = frameSeenNum;
+                }
+                _last_seq_seen = frameSeenNum;
+            }
+            _position_within_gop_header = 0;
+        }
+    }
+#undef AVG_KEYFRAME_DIFF
+#undef MAX_KEYFRAME_DIFF
+#undef DEBUG_FIND_KEY_FRAMES
+
+    return hasKeyFrame || (_payload_buffer.size() >= (188*50));
+}
+
+/*
+bool DTVRecorder::FindKeyframes(const TSPacket* tspacket)
+{
     bool haveBufferedData = !_payload_buffer.empty();
     if (!tspacket->HasPayload()) // no payload to scan
         return !haveBufferedData;
@@ -273,6 +370,7 @@
 
     return hasKeyFrame || (_payload_buffer.size() >= (188*50));
 }
+*/
 
 // documented in recorderbase.h
 void DTVRecorder::SetNextRecording(const ProgramInfo *progInf, RingBuffer *rb)
