Index: mythtv/libs/libmythtv/dbox2recorder.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/dbox2recorder.cpp	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/dbox2recorder.cpp	2005-11-24 12:33:29.000000000 +0000
@@ -527,21 +527,19 @@
 	// Inject PAT every 2000 TS packets.
 	if (pkts_until_pat == 0) 
 	{
-	    BufferedWrite(*(reinterpret_cast<const TSPacket*>(m_patPacket)));
+	    ringBuffer->Write(m_patPacket, 188);
 	    pkts_until_pat = 2000;
 	}
 	else
 	    pkts_until_pat--;
 
-        const void     *data     = stream->buffer + readIndex + tsPos;
-        const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(data);
-
-	_buffer_packets = !FindKeyframes(tspacket);
-
-	BufferedWrite(*tspacket);
+	tpkt.InitHeader(stream->buffer+readIndex+tsPos);
+	tpkt.InitPayload(stream->buffer+readIndex+tsPos+4);
+	FindKeyframes(&tpkt);
 
+	ringBuffer->Write(stream->buffer+readIndex+tsPos, 188);
 	lastpacket = time(NULL);
-	readIndex += tsPos + TSPacket::SIZE;
+	readIndex += tsPos + 188;
     }
 
     memcpy(stream->buffer, stream->buffer + readIndex, bufferSize - readIndex);
Index: mythtv/libs/libmythtv/dbox2recorder.h
===================================================================
--- mythtv.orig/libs/libmythtv/dbox2recorder.h	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/dbox2recorder.h	2005-11-24 12:33:29.000000000 +0000
@@ -101,6 +101,7 @@
 	time_t lastpacket;
 	int bufferSize;
 	stream_meta transportStream;
+	TSPacket tpkt;
 	int m_videoWidth;
 	int m_videoHeight;
 	QString m_videoFormat;
Index: mythtv/libs/libmythtv/dtvrecorder.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/dtvrecorder.cpp	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/dtvrecorder.cpp	2005-11-24 12:33:29.000000000 +0000
@@ -45,11 +45,10 @@
     _wait_for_keyframe(true),
     // state
     _recording(false),
+    _streamid_not_in_first_ts_packet(false),
     _error(false),
     // TS packet buffer
     _buffer(0),                     _buffer_size(0),
-    // keyframe TS buffer
-    _buffer_packets(false),
     // statistics
     _frames_seen_count(0),          _frames_written_count(0)
 {
@@ -57,6 +56,11 @@
 
 DTVRecorder::~DTVRecorder()
 {
+    if (_streamid_not_in_first_ts_packet)
+    {
+        VERBOSE(VB_IMPORTANT, LOC +
+                "Saw keyframe stream_id which was not in first TS Packet.");
+    }
 }
 
 /** \fn DTVRecorder::SetOption(const QString&,int)
@@ -132,6 +136,7 @@
     _last_gop_seen              = 0;
     _last_seq_seen              = 0;
     //_recording
+    //_streamid_not_in_first_ts_packet
     _error                      = false;
     //_buffer
     //_buffer_size
@@ -141,32 +146,6 @@
     _position_map_delta.clear();
 }
 
-void DTVRecorder::BufferedWrite(const TSPacket &tspacket)
-{
-    // delay until first GOP to avoid decoder crash on res change
-    if (_wait_for_keyframe && !_keyframe_seen)
-        return;
-
-    // Do we have to buffer the packet for exact keyframe detection?
-    if (_buffer_packets)
-    {
-        int idx = _payload_buffer.size();
-        _payload_buffer.resize(idx + TSPacket::SIZE);
-        memcpy(&_payload_buffer[idx], tspacket.data(), TSPacket::SIZE);
-        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())
-    {
-        ringBuffer->Write(&_payload_buffer[0], _payload_buffer.size());
-        _payload_buffer.clear();
-    }
-
-    ringBuffer->Write(tspacket.data(), TSPacket::SIZE);
-}
-
 /** \fn DTVRecorder::FindKeyframes(const TSPacket* tspacket)
  *  \brief Locates the keyframes and saves them to the position map.
  *
@@ -178,19 +157,17 @@
  *   streams, and if all else fails we just look for the picture
  *   start codes and call every 16th frame a keyframe.
  *
- *  \startcode
+ * \startcode
  *   PES header format
  *   byte 0  byte 1  byte 2  byte 3      [byte 4     byte 5]
  *   0x00    0x00    0x01    PESStreamID  PES packet length
- *  \endcode
+ * \endcode
  *
- *  \return Returns true if packet[s] should be output.
  */
-bool DTVRecorder::FindKeyframes(const TSPacket* tspacket)
+void DTVRecorder::FindKeyframes(const TSPacket* tspacket)
 {
-    bool haveBufferedData = !_payload_buffer.empty();
-    if (!tspacket->HasPayload()) // no payload to scan
-        return !haveBufferedData;
+    if (!tspacket->HasPayload())
+        return; // no payload to scan
 
     // if packet contains start of PES packet, start
     // looking for first byte of MPEG start code (3 bytes 0 0 1)
@@ -199,11 +176,6 @@
     _position_within_gop_header = (payloadStart) ?
         0 : _position_within_gop_header;
 
-    // if this is not a payload start packet, and aren't waiting
-    // for anything then just output this packet..
-    if (!payloadStart && !haveBufferedData)
-        return true;
-
     // Just make these local for efficiency reasons (gcc not so smart..)
     const uint maxKFD            = kMaxKeyFrameDistance;
     const long long frameSeenNum = _frames_seen_count;
@@ -270,12 +242,21 @@
     {
         _last_keyframe_seen = frameSeenNum;
         HandleKeyframe();
-        return true;
-    }
-    else
-    {
-        uint idx = _payload_buffer.size();
-        return (idx >= 10*TSPacket::SIZE);
+
+        if (!payloadStart && !_streamid_not_in_first_ts_packet)
+        {
+            VERBOSE(VB_IMPORTANT, LOC +
+                    "Keyframe stream_id not in first TS Packet.\n"
+                    "This is not an error, but MythTV may not always handle\n"
+                    "this gracefully. If you would like it to, please inform\n"
+                    "the mythtv developer mailing list of this message.\n");
+            // If this happens in practice, it means we need to buffer
+            // all TS packets after the first payload start until
+            // we determine the PES stream ID; and then only write
+            // data to the ringbuffer after we determine the PES stream ID
+            // and call HandleKeyframe() if needed.
+            _streamid_not_in_first_ts_packet = true;
+        }
     }
 }
 
Index: mythtv/libs/libmythtv/dtvrecorder.h
===================================================================
--- mythtv.orig/libs/libmythtv/dtvrecorder.h	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/dtvrecorder.h	2005-11-24 12:33:29.000000000 +0000
@@ -9,9 +9,6 @@
 #ifndef DTVRECORDER_H
 #define DTVRECORDER_H
 
-#include <vector>
-using namespace std;
-
 #include "recorderbase.h"
 
 class TSPacket;
@@ -47,12 +44,10 @@
     void FinishRecording(void);
     void ResetForNewFile(void);
 
-    bool FindKeyframes(const TSPacket* tspacket);
+    void FindKeyframes(const TSPacket* tspacket);
     void HandleKeyframe();
     void SavePositionMap(bool force);
 
-    void BufferedWrite(const TSPacket &tspacket);
-
     // file handle for stream
     int _stream_fd;
 
@@ -73,6 +68,9 @@
     // state tracking variables
     /// True iff recording is actually being performed
     bool _recording;
+    /// True iff a frame PESStreamID seen outside first TS Packet
+    /// containing a PES Packet
+    bool _streamid_not_in_first_ts_packet;
     /// True iff irrecoverable recording error detected
     bool _error;
 
@@ -80,10 +78,6 @@
     unsigned char* _buffer;
     int            _buffer_size;
 
-    // keyframe finding buffer
-    bool                  _buffer_packets;
-    vector<unsigned char> _payload_buffer;
-
     // statistics
     long long _frames_seen_count;
     long long _frames_written_count;
Index: mythtv/libs/libmythtv/dvbrecorder.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/dvbrecorder.cpp	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/dvbrecorder.cpp	2005-11-24 12:37:22.000000000 +0000
@@ -362,6 +362,7 @@
     _payload_start_seen.clear();
     data_found = false;
     _wait_for_keyframe = _wait_for_keyframe_option;
+    keyframe_found = false;
 
     _ps_rec_audio_id = 0xC0;
     _ps_rec_video_id = 0xE0;
@@ -769,7 +770,52 @@
             }
 
             if (_record_transport_stream_option)
-                ProcessTSPacket(*(reinterpret_cast<const TSPacket*>(pktbuf)));
+            {   // handle TS recording
+                MythTimer t;
+                t.start();
+                if (_videoPID[pid])
+                {
+                    // Check for keyframe
+                    const TSPacket *pkt =
+                        reinterpret_cast<const TSPacket*>(pktbuf);
+                    FindKeyframes(pkt);
+                }
+                if (t.elapsed() > 10)
+                {
+                    VERBOSE(VB_RECORD, LOC_WARN +
+                            QString("Find keyframes took %1 ms!")
+                            .arg(t.elapsed()));
+                }
+
+                // Sync recording start to first keyframe
+                if (_wait_for_keyframe && !_keyframe_seen)
+                    continue;
+                if (!keyframe_found)
+                {
+                    keyframe_found = true;
+                    VERBOSE(VB_RECORD, QString("Found first keyframe"));
+                }
+
+                // Sync streams to the first Payload Unit Start Indicator
+                // _after_ first keyframe iff _wait_for_keyframe is true
+                if (!_payload_start_seen[pid])
+                {
+                    if ((pktbuf[1] & 0x40) == 0)
+                        continue; // not payload start - drop packet
+
+                    VERBOSE(VB_RECORD, QString("Found Payload Start for PID %1").arg(pid));
+                    _payload_start_seen[pid] = true;
+                }
+
+                t.start();
+                LocalProcessDataTS(pktbuf, MPEG_TS_PKT_SIZE);
+                if (t.elapsed() > 10)
+                {
+                    VERBOSE(VB_RECORD, LOC_WARN +
+                            QString("TS packet write took %1 ms!")
+                            .arg(t.elapsed()));
+                }
+            }
             else
             {   // handle PS recording
                 ipack *ip = _ps_rec_pid_ipack[pid];
@@ -800,47 +846,6 @@
     }
 }
 
-// handle TS recording
-bool DVBRecorder::ProcessTSPacket(const TSPacket& tspacket)
-{
-    // Check video pids for keyframes
-    if (_videoPID[tspacket.PID()])
-        _buffer_packets = !FindKeyframes(&tspacket);
-
-    // If haven't seen a keyframe yet and we are supposed to wait for the
-    // first keyframe before starting a recording, then return early...
-    if (_wait_for_keyframe && !_keyframe_seen)
-        return true;
-
-    // Sync each stream to the first Payload Start
-    // _after_ first keyframe iff _wait_for_keyframe is true
-    if (!_payload_start_seen[tspacket.PID()])
-    {
-        if (!tspacket.PayloadStart())
-            return true; // not payload start - drop packet
-        VERBOSE(VB_RECORD, LOC + "Found first payload start for " +
-                QString("PID 0x%1").arg(tspacket.PID(),0,16));
-        _payload_start_seen[tspacket.PID()] = true;
-    }
-
-    // Write out PAT & PMT on occasion...
-    int pktCnt = _payload_buffer.size() / TSPacket::SIZE;
-    _ts_packets_until_psip_sync -= (pktCnt + 1);
-    {
-        QMutexLocker read_lock(&_pid_lock);
-        if (_ts_packets_until_psip_sync <= 0 && _pat && _pmt)
-        {
-            BufferedWrite(*(reinterpret_cast<TSPacket*>(_pat->tsheader())));
-            BufferedWrite(*(reinterpret_cast<TSPacket*>(_pmt->tsheader())));
-            _ts_packets_until_psip_sync = TSPACKETS_BETWEEN_PSIP_SYNC;
-        }
-    }
-
-    BufferedWrite(tspacket);
-
-    return true;
-}
-
 #define SEQ_START     0x000001B3
 #define GOP_START     0x000001B8
 #define PICTURE_START 0x00000100
@@ -921,8 +926,21 @@
         ringBuffer->Write(buffer, len);
 }
 
-void DVBRecorder::LocalProcessDataTS(const unsigned char *buffer, uint len)
+void DVBRecorder::LocalProcessDataTS(unsigned char *buffer, int len)
 {
+    QMutexLocker read_lock(&_pid_lock);
+    if (_ts_packets_until_psip_sync == 0)
+    {
+        if (_pat && _pmt)
+        {
+            ringBuffer->Write(_pat->tsheader()->data(), TSPacket::SIZE);
+            ringBuffer->Write(_pmt->tsheader()->data(), TSPacket::SIZE);
+            _ts_packets_until_psip_sync = TSPACKETS_BETWEEN_PSIP_SYNC;
+        }
+    }
+    else
+        _ts_packets_until_psip_sync--;
+
     ringBuffer->Write(buffer,len);
 }
 
Index: mythtv/libs/libmythtv/dvbrecorder.h
===================================================================
--- mythtv.orig/libs/libmythtv/dvbrecorder.h	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/dvbrecorder.h	2005-11-24 12:33:29.000000000 +0000
@@ -24,7 +24,6 @@
 
 class ProgramAssociationTable;
 class ProgramMapTable;
-class TSPacket;
 
 /** \class DVBRecorder
  *  \brief This is a specialization of DTVRecorder used to
@@ -67,8 +66,7 @@
     void ReadFromDMX(void);
     static void ProcessDataPS(unsigned char *buffer, int len, void *priv);
     void LocalProcessDataPS(unsigned char *buffer, int len);
-    bool ProcessTSPacket(const TSPacket &tspacket);
-    void LocalProcessDataTS(const unsigned char *buffer, uint len);
+    void LocalProcessDataTS(unsigned char *buffer, int len);
 
     void CloseFilters(void);
     void OpenFilter(uint pid, ES_Type type, dmx_pes_type_t pes_type,
@@ -102,7 +100,7 @@
     ProgramAssociationTable *_pat;
     ProgramMapTable         *_pmt;
     uint            _next_pmt_version;
-    int             _ts_packets_until_psip_sync;
+    uint            _ts_packets_until_psip_sync;
     QMap<uint,bool> _payload_start_seen;
     QMap<uint,bool> _videoPID;
 
@@ -129,6 +127,7 @@
 
     // For debugging
     bool data_found; ///< debugging variable used by transform.c
+    bool keyframe_found;
 
     // Constants
     static const int PMT_PID;
Index: mythtv/libs/libmythtv/firewirerecorder.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/firewirerecorder.cpp	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/firewirerecorder.cpp	2005-11-24 12:33:29.000000000 +0000
@@ -15,33 +15,27 @@
 // MythTV includes
 #include "firewirerecorder.h"
 #include "mythcontext.h"
+#include "RingBuffer.h"
 #include "tspacket.h"
 #include "tv_rec.h"
 
 // callback function for libiec61883
-int read_tspacket (unsigned char *tspacket, int /*len*/,
-                   uint dropped, void *callback_data)
-{
-    FirewireRecorder *fw = (FirewireRecorder*) callback_data;
+int read_tspacket (unsigned char *tspacket, int len, unsigned int dropped, void *callback_data) {
 
-    if (!fw)
-        return 0;
+     FirewireRecorder *fw = (FirewireRecorder*)callback_data;
+     if (!fw) return 0;
 
-    if (dropped)
-    {
-        VERBOSE(VB_RECORD,
-                QString("Firewire: %1 packet(s) dropped.").arg(dropped));
-    }
-
-    if (SYNC_BYTE != tspacket[0])
-    {
-        VERBOSE(VB_IMPORTANT, "Firewire: Got out of sync TS Packet");
-        return 1;
-    }
+     if (dropped) {
+         VERBOSE(VB_GENERAL,QString("Firewire: %1 packet(s) dropped.").arg(dropped));
+     }
 
-    fw->ProcessTSPacket(*(reinterpret_cast<TSPacket*>(tspacket)));
+     if (tspacket[0] == SYNC_BYTE) {
+         fw->ProcessTSPacket(tspacket,len);
+     } else {
+        VERBOSE(VB_GENERAL,QString("Firewire: out of sync mpeg2ts packet"));
+     }
 
-    return 1;
+     return 1;
 }
 
 void FirewireRecorder::deleteLater(void)
@@ -189,11 +183,12 @@
     _recording = false;
 }  
 
-void FirewireRecorder::ProcessTSPacket(const TSPacket &tspacket)
-{
+void FirewireRecorder::ProcessTSPacket(unsigned char *tspacket, int len) {
+    tpkt.InitHeader(tspacket);
+    tpkt.InitPayload(tspacket+4);
+    FindKeyframes(&tpkt);
     lastpacket = time(NULL);
-    _buffer_packets = !FindKeyframes(&tspacket);
-    BufferedWrite(tspacket);
+    ringBuffer->Write(tspacket,len);
 }
 
 void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
Index: mythtv/libs/libmythtv/firewirerecorder.h
===================================================================
--- mythtv.orig/libs/libmythtv/firewirerecorder.h	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/firewirerecorder.h	2005-11-24 12:33:29.000000000 +0000
@@ -41,7 +41,7 @@
 
     void StartRecording(void);
     bool Open(void); 
-    void ProcessTSPacket(const TSPacket &tspacket);
+    void ProcessTSPacket(unsigned char *tspacket, int len);
     void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
                                          const QString &videodev,
                                          const QString &audiodev,
@@ -66,6 +66,7 @@
     iec61883_mpeg2_t fwmpeg;
     bool isopen;
     time_t lastpacket;
+    TSPacket tpkt;
 };
 
 #endif
Index: mythtv/libs/libmythtv/hdtvrecorder.cpp
===================================================================
--- mythtv.orig/libs/libmythtv/hdtvrecorder.cpp	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/hdtvrecorder.cpp	2005-11-24 12:33:29.000000000 +0000
@@ -110,9 +110,7 @@
 #endif
 
 HDTVRecorder::HDTVRecorder(TVRec *rec)
-    : DTVRecorder(rec, "HDTVRecorder"),
-      _atsc_stream_data(NULL),
-      _resync_count(0)
+    : DTVRecorder(rec, "HDTVRecorder"), _atsc_stream_data(0), _resync_count(0)
 {
     _atsc_stream_data = new ATSCStreamData(-1, DEFAULT_SUBCHANNEL);
     connect(_atsc_stream_data, SIGNAL(UpdatePATSingleProgram(
@@ -689,17 +687,15 @@
     return paused;
 }
 
-int HDTVRecorder::ResyncStream(const unsigned char *buffer,
-                               uint curr_pos, uint len)
+int HDTVRecorder::ResyncStream(unsigned char *buffer, int curr_pos, int len)
 {
     // Search for two sync bytes 188 bytes apart, 
-    uint pos = curr_pos;
-    uint nextpos = pos + TSPacket::SIZE;
+    int pos = curr_pos;
+    int nextpos = pos + TSPacket::SIZE;
     if (nextpos >= len)
         return -1; // not enough bytes; caller should try again
     
-    while (buffer[pos] != SYNC_BYTE || buffer[nextpos] != SYNC_BYTE)
-    {
+    while (buffer[pos] != SYNC_BYTE || buffer[nextpos] != SYNC_BYTE) {
         pos++;
         nextpos++;
         if (nextpos == len)
@@ -711,22 +707,81 @@
 
 void HDTVRecorder::WritePAT(ProgramAssociationTable *pat)
 {
-    if (!pat)
-        return;
-
     int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
     pat->tsheader()->SetContinuityCounter(next);
-    BufferedWrite(*(reinterpret_cast<TSPacket*>(pat->tsheader())));
+    ringBuffer->Write(pat->tsheader()->data(), TSPacket::SIZE);
 }
 
+#if WHACK_A_BUG_VIDEO
+static int WABV_base_pid     = 0x100;
+#define WABV_WAIT 60
+static int WABV_wait_a_while = WABV_WAIT;
+bool WABV_started = false;
+#endif
+
+#if WHACK_A_BUG_AUDIO
+static int WABA_base_pid     = 0x200;
+#define WABA_WAIT 60
+static int WABA_wait_a_while = WABA_WAIT;
+bool WABA_started = false;
+#endif
+
 void HDTVRecorder::WritePMT(ProgramMapTable* pmt)
 {
-    if (!pmt)
-        return;
+    if (pmt) {
+        int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
+        pmt->tsheader()->SetContinuityCounter(next);
+
+#if WHACK_A_BUG_VIDEO
+        WABV_wait_a_while--;
+        if (WABV_wait_a_while<=0) {
+            WABV_started = true;
+            WABV_wait_a_while = WABV_WAIT;
+            WABV_base_pid = (((WABV_base_pid-0x100)+1)%32)+0x100;
+            if (StreamID::MPEG2Video != StreamData()->PMT()->StreamType(0))
+            {
+                VERBOSE(VB_IMPORTANT, "HDTVRecorder::WritePMT(): Error,"
+                        "Whack a Bug can not rewrite PMT, wrong stream type");
+            }
+            else
+            {
+                VERBOSE(VB_IMPORTANT, QString("Whack a Bug: new video pid %1").
+                        arg(WABV_base_pid));
+                // rewrite video pid
+                const uint old_video_pid=StreamData()->PMT()->StreamPID(0);
+                StreamData()->PMT()->SetStreamPID(0, WABV_base_pid);
+                if (StreamData()->PMT()->PCRPID() == old_video_pid)
+                    StreamData()->PMT()->SetPCRPID(WABV_base_pid);
+                StreamData()->PMT()->SetCRC(StreamData()->PMT()->CalcCRC());
+                VERBOSE(VB_IMPORTANT, StreamData()->PMT()->toString());
+            }
+        }
+#endif
+#if WHACK_A_BUG_AUDIO
+        WABA_wait_a_while--;
+        if (WABA_wait_a_while<=0) {
+            WABA_started = true;
+            WABA_wait_a_while = WABA_WAIT;
+            WABA_base_pid = (((WABA_base_pid-0x200)+1)%32)+0x200;
+            VERBOSE(VB_IMPORTANT, QString("Whack a Bug: new audio BASE pid %1").arg(WABA_base_pid));
+            // rewrite audio pids
+            for (uint i=0; i<StreamData()->PMT()->StreamCount(); i++) {
+                if (StreamID::MPEG2Audio == StreamData()->PMT()->StreamType(i) ||
+                    StreamID::MPEG2Audio == StreamData()->PMT()->StreamType(i)) {
+                    const uint old_audio_pid = StreamData()->PMT()->StreamPID(i);
+                    const uint new_audio_pid = WABA_base_pid + old_audio_pid;
+                    StreamData()->PMT()->SetStreamPID(i, new_audio_pid);
+                    if (StreamData()->PMT()->PCRPID() == old_audio_pid)
+                        StreamData()->PMT()->SetPCRPID(new_audio_pid);
+                    StreamData()->PMT()->SetCRC(StreamData()->PMT()->CalcCRC());
+                    VERBOSE(VB_IMPORTANT, StreamData()->PMT()->toString());
+                }
+            }
+        }
+#endif
 
-    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
-    pmt->tsheader()->SetContinuityCounter(next);
-    BufferedWrite(*(reinterpret_cast<TSPacket*>(pmt->tsheader())));
+        ringBuffer->Write(pmt->tsheader()->data(), TSPacket::SIZE);
+    }
 }
 
 /** \fn HDTVRecorder::ProcessMGT(const MasterGuideTable*)
@@ -791,7 +846,37 @@
     }
 }
 
-bool HDTVRecorder::ProcessTSPacket(const TSPacket &tspacket)
+void HDTVRecorder::HandleVideo(const TSPacket* tspacket)
+{
+    FindKeyframes(tspacket);
+    // decoder needs video, of course (just this PID)
+    // delay until first GOP to avoid decoder crash on res change
+    if (_wait_for_keyframe && !_keyframe_seen)
+        return;
+
+#if WHACK_A_BUG_VIDEO
+    if (WABV_started)
+        ((TSPacket*)(tspacket))->SetPID(WABV_base_pid);
+#endif
+
+    ringBuffer->Write(tspacket->data(), TSPacket::SIZE);
+}
+
+void HDTVRecorder::HandleAudio(const TSPacket* tspacket)
+{
+    // decoder needs audio, of course (just this PID)
+    if (_wait_for_keyframe && !_keyframe_seen)
+        return;
+
+#if WHACK_A_BUG_AUDIO
+    if (WABA_started)
+        ((TSPacket*)(tspacket))->SetPID(WABA_base_pid+tspacket->PID());
+#endif
+
+    ringBuffer->Write(tspacket->data(), TSPacket::SIZE);
+}
+
+bool HDTVRecorder::ProcessTSPacket(const TSPacket& tspacket)
 {
     bool ok = !tspacket.TransportError();
     if (ok && !tspacket.ScramplingControl())
@@ -803,16 +888,13 @@
             const unsigned int lpid = tspacket.PID();
             // Pass or reject frames based on PID, and parse info from them
             if (lpid == StreamData()->VideoPIDSingleProgram())
-            {
-                _buffer_packets = !FindKeyframes(&tspacket);
-                BufferedWrite(tspacket);
-            }
+                HandleVideo(&tspacket);
             else if (StreamData()->IsAudioPID(lpid))
-                BufferedWrite(tspacket);
+                HandleAudio(&tspacket);
             else if (StreamData()->IsListeningPID(lpid))
                 StreamData()->HandleTSTables(&tspacket);
             else if (StreamData()->IsWritingPID(lpid))
-                BufferedWrite(tspacket);
+                ringBuffer->Write(tspacket.data(), TSPacket::SIZE);
             else if (StreamData()->VersionMGT()>=0)
                 _ts_stats.IncrPIDCount(lpid);
         }
@@ -820,9 +902,9 @@
     return ok;
 }
 
-int HDTVRecorder::ProcessData(const unsigned char *buffer, uint len)
+int HDTVRecorder::ProcessData(unsigned char *buffer, int len)
 {
-    uint pos = 0;
+    int pos = 0;
 
     while (pos + 187 < len) // while we have a whole packet left
     {
@@ -843,17 +925,13 @@
         }
 
         const TSPacket *pkt = reinterpret_cast<const TSPacket*>(&buffer[pos]);
-        if (ProcessTSPacket(*pkt))
-        {
+        if (ProcessTSPacket(*pkt)) {
             pos += TSPacket::SIZE; // Advance to next TS packet
             _ts_stats.IncrTSPacketCount();
             if (0 == _ts_stats.TSPacketCount()%1000000)
                 VERBOSE(VB_RECORD, _ts_stats.toString());
-        }
-        else
-        { // Let it resync in case of dropped bytes
-            pos++;
-        }
+        } else // Let it resync in case of dropped bytes
+            buffer[pos] = SYNC_BYTE+1;
     }
 
     return len - pos;
Index: mythtv/libs/libmythtv/hdtvrecorder.h
===================================================================
--- mythtv.orig/libs/libmythtv/hdtvrecorder.h	2005-11-24 12:32:03.000000000 +0000
+++ mythtv/libs/libmythtv/hdtvrecorder.h	2005-11-24 12:33:29.000000000 +0000
@@ -62,10 +62,12 @@
 
   private:
     void TeardownAll(void);
+    int ProcessData(unsigned char *buffer, int len);
+    bool ProcessTSPacket(const TSPacket& tspacket);
+    void HandleVideo(const TSPacket* tspacket);
+    void HandleAudio(const TSPacket* tspacket);
 
-    int  ProcessData    (const unsigned char *buffer, uint len);
-    int  ResyncStream   (const unsigned char *buffer, uint pos, uint len);
-    bool ProcessTSPacket(const TSPacket &tspacket);
+    int ResyncStream(unsigned char *buffer, int curr_pos, int len);
 
     static void *boot_ringbuffer(void *);
     void fill_ringbuffer(void);
