Ticket #692: Changeset7902-revert.diff

File Changeset7902-revert.diff, 25.2 KB (added by Stuart Auchterlonie, 18 years ago)

Reverts Changeset 7902, applies over 8035

  • libs/libmythtv/dbox2recorder.cpp

    old new  
    527527        // Inject PAT every 2000 TS packets.
    528528        if (pkts_until_pat == 0)
    529529        {
    530             BufferedWrite(*(reinterpret_cast<const TSPacket*>(m_patPacket)));
     530            ringBuffer->Write(m_patPacket, 188);
    531531            pkts_until_pat = 2000;
    532532        }
    533533        else
    534534            pkts_until_pat--;
    535535
    536         const void     *data     = stream->buffer + readIndex + tsPos;
    537         const TSPacket *tspacket = reinterpret_cast<const TSPacket*>(data);
    538 
    539         _buffer_packets = !FindKeyframes(tspacket);
    540 
    541         BufferedWrite(*tspacket);
     536        tpkt.InitHeader(stream->buffer+readIndex+tsPos);
     537        tpkt.InitPayload(stream->buffer+readIndex+tsPos+4);
     538        FindKeyframes(&tpkt);
    542539
     540        ringBuffer->Write(stream->buffer+readIndex+tsPos, 188);
    543541        lastpacket = time(NULL);
    544         readIndex += tsPos + TSPacket::SIZE;
     542        readIndex += tsPos + 188;
    545543    }
    546544
    547545    memcpy(stream->buffer, stream->buffer + readIndex, bufferSize - readIndex);
  • libs/libmythtv/dbox2recorder.h

    old new  
    101101        time_t lastpacket;
    102102        int bufferSize;
    103103        stream_meta transportStream;
     104        TSPacket tpkt;
    104105        int m_videoWidth;
    105106        int m_videoHeight;
    106107        QString m_videoFormat;
  • libs/libmythtv/dtvrecorder.cpp

    old new  
    4545    _wait_for_keyframe(true),
    4646    // state
    4747    _recording(false),
     48    _streamid_not_in_first_ts_packet(false),
    4849    _error(false),
    4950    // TS packet buffer
    5051    _buffer(0),                     _buffer_size(0),
    51     // keyframe TS buffer
    52     _buffer_packets(false),
    5352    // statistics
    5453    _frames_seen_count(0),          _frames_written_count(0)
    5554{
     
    5756
    5857DTVRecorder::~DTVRecorder()
    5958{
     59    if (_streamid_not_in_first_ts_packet)
     60    {
     61        VERBOSE(VB_IMPORTANT, LOC +
     62                "Saw keyframe stream_id which was not in first TS Packet.");
     63    }
    6064}
    6165
    6266/** \fn DTVRecorder::SetOption(const QString&,int)
     
    132136    _last_gop_seen              = 0;
    133137    _last_seq_seen              = 0;
    134138    //_recording
     139    //_streamid_not_in_first_ts_packet
    135140    _error                      = false;
    136141    //_buffer
    137142    //_buffer_size
     
    141146    _position_map_delta.clear();
    142147}
    143148
    144 void DTVRecorder::BufferedWrite(const TSPacket &tspacket)
    145 {
    146     // delay until first GOP to avoid decoder crash on res change
    147     if (_wait_for_keyframe && !_keyframe_seen)
    148         return;
    149 
    150     // Do we have to buffer the packet for exact keyframe detection?
    151     if (_buffer_packets)
    152     {
    153         int idx = _payload_buffer.size();
    154         _payload_buffer.resize(idx + TSPacket::SIZE);
    155         memcpy(&_payload_buffer[idx], tspacket.data(), TSPacket::SIZE);
    156         return;
    157     }
    158 
    159     // We are free to write the packet, but if we have buffered packet[s]
    160     // we have to write them first...
    161     if (!_payload_buffer.empty())
    162     {
    163         ringBuffer->Write(&_payload_buffer[0], _payload_buffer.size());
    164         _payload_buffer.clear();
    165     }
    166 
    167     ringBuffer->Write(tspacket.data(), TSPacket::SIZE);
    168 }
    169 
    170149/** \fn DTVRecorder::FindKeyframes(const TSPacket* tspacket)
    171150 *  \brief Locates the keyframes and saves them to the position map.
    172151 *
     
    178157 *   streams, and if all else fails we just look for the picture
    179158 *   start codes and call every 16th frame a keyframe.
    180159 *
    181  *  \startcode
     160 * \startcode
    182161 *   PES header format
    183162 *   byte 0  byte 1  byte 2  byte 3      [byte 4     byte 5]
    184163 *   0x00    0x00    0x01    PESStreamID  PES packet length
    185  *  \endcode
     164 * \endcode
    186165 *
    187  *  \return Returns true if packet[s] should be output.
    188166 */
    189 bool DTVRecorder::FindKeyframes(const TSPacket* tspacket)
     167void DTVRecorder::FindKeyframes(const TSPacket* tspacket)
    190168{
    191     bool haveBufferedData = !_payload_buffer.empty();
    192     if (!tspacket->HasPayload()) // no payload to scan
    193         return !haveBufferedData;
     169    if (!tspacket->HasPayload())
     170        return; // no payload to scan
    194171
    195172    // if packet contains start of PES packet, start
    196173    // looking for first byte of MPEG start code (3 bytes 0 0 1)
     
    199176    _position_within_gop_header = (payloadStart) ?
    200177        0 : _position_within_gop_header;
    201178
    202     // if this is not a payload start packet, and aren't waiting
    203     // for anything then just output this packet..
    204     if (!payloadStart && !haveBufferedData)
    205         return true;
    206 
    207179    // Just make these local for efficiency reasons (gcc not so smart..)
    208180    const uint maxKFD            = kMaxKeyFrameDistance;
    209181    const long long frameSeenNum = _frames_seen_count;
     
    270242    {
    271243        _last_keyframe_seen = frameSeenNum;
    272244        HandleKeyframe();
    273         return true;
    274     }
    275     else
    276     {
    277         uint idx = _payload_buffer.size();
    278         return (idx >= 10*TSPacket::SIZE);
     245
     246        if (!payloadStart && !_streamid_not_in_first_ts_packet)
     247        {
     248            VERBOSE(VB_IMPORTANT, LOC +
     249                    "Keyframe stream_id not in first TS Packet.\n"
     250                    "This is not an error, but MythTV may not always handle\n"
     251                    "this gracefully. If you would like it to, please inform\n"
     252                    "the mythtv developer mailing list of this message.\n");
     253            // If this happens in practice, it means we need to buffer
     254            // all TS packets after the first payload start until
     255            // we determine the PES stream ID; and then only write
     256            // data to the ringbuffer after we determine the PES stream ID
     257            // and call HandleKeyframe() if needed.
     258            _streamid_not_in_first_ts_packet = true;
     259        }
    279260    }
    280261}
    281262
  • libs/libmythtv/dtvrecorder.h

    old new  
    99#ifndef DTVRECORDER_H
    1010#define DTVRECORDER_H
    1111
    12 #include <vector>
    13 using namespace std;
    14 
    1512#include "recorderbase.h"
    1613
    1714class TSPacket;
     
    4744    void FinishRecording(void);
    4845    void ResetForNewFile(void);
    4946
    50     bool FindKeyframes(const TSPacket* tspacket);
     47    void FindKeyframes(const TSPacket* tspacket);
    5148    void HandleKeyframe();
    5249    void SavePositionMap(bool force);
    5350
    54     void BufferedWrite(const TSPacket &tspacket);
    55 
    5651    // file handle for stream
    5752    int _stream_fd;
    5853
     
    7368    // state tracking variables
    7469    /// True iff recording is actually being performed
    7570    bool _recording;
     71    /// True iff a frame PESStreamID seen outside first TS Packet
     72    /// containing a PES Packet
     73    bool _streamid_not_in_first_ts_packet;
    7674    /// True iff irrecoverable recording error detected
    7775    bool _error;
    7876
     
    8078    unsigned char* _buffer;
    8179    int            _buffer_size;
    8280
    83     // keyframe finding buffer
    84     bool                  _buffer_packets;
    85     vector<unsigned char> _payload_buffer;
    86 
    8781    // statistics
    8882    long long _frames_seen_count;
    8983    long long _frames_written_count;
  • libs/libmythtv/dvbrecorder.cpp

    old new  
    362362    _payload_start_seen.clear();
    363363    data_found = false;
    364364    _wait_for_keyframe = _wait_for_keyframe_option;
     365    keyframe_found = false;
    365366
    366367    _ps_rec_audio_id = 0xC0;
    367368    _ps_rec_video_id = 0xE0;
     
    769770            }
    770771
    771772            if (_record_transport_stream_option)
    772                 ProcessTSPacket(*(reinterpret_cast<const TSPacket*>(pktbuf)));
     773            {   // handle TS recording
     774                MythTimer t;
     775                t.start();
     776                if (_videoPID[pid])
     777                {
     778                    // Check for keyframe
     779                    const TSPacket *pkt =
     780                        reinterpret_cast<const TSPacket*>(pktbuf);
     781                    FindKeyframes(pkt);
     782                }
     783                if (t.elapsed() > 10)
     784                {
     785                    VERBOSE(VB_RECORD, LOC_WARN +
     786                            QString("Find keyframes took %1 ms!")
     787                            .arg(t.elapsed()));
     788                }
     789
     790                // Sync recording start to first keyframe
     791                if (_wait_for_keyframe && !_keyframe_seen)
     792                    continue;
     793                if (!keyframe_found)
     794                {
     795                    keyframe_found = true;
     796                    VERBOSE(VB_RECORD, QString("Found first keyframe"));
     797                }
     798
     799                // Sync streams to the first Payload Unit Start Indicator
     800                // _after_ first keyframe iff _wait_for_keyframe is true
     801                if (!_payload_start_seen[pid])
     802                {
     803                    if ((pktbuf[1] & 0x40) == 0)
     804                        continue; // not payload start - drop packet
     805
     806                    VERBOSE(VB_RECORD, QString("Found Payload Start for PID %1").arg(pid));
     807                    _payload_start_seen[pid] = true;
     808                }
     809
     810                t.start();
     811                LocalProcessDataTS(pktbuf, MPEG_TS_PKT_SIZE);
     812                if (t.elapsed() > 10)
     813                {
     814                    VERBOSE(VB_RECORD, LOC_WARN +
     815                            QString("TS packet write took %1 ms!")
     816                            .arg(t.elapsed()));
     817                }
     818            }
    773819            else
    774820            {   // handle PS recording
    775821                ipack *ip = _ps_rec_pid_ipack[pid];
     
    800846    }
    801847}
    802848
    803 // handle TS recording
    804 bool DVBRecorder::ProcessTSPacket(const TSPacket& tspacket)
    805 {
    806     // Check video pids for keyframes
    807     if (_videoPID[tspacket.PID()])
    808         _buffer_packets = !FindKeyframes(&tspacket);
    809 
    810     // If haven't seen a keyframe yet and we are supposed to wait for the
    811     // first keyframe before starting a recording, then return early...
    812     if (_wait_for_keyframe && !_keyframe_seen)
    813         return true;
    814 
    815     // Sync each stream to the first Payload Start
    816     // _after_ first keyframe iff _wait_for_keyframe is true
    817     if (!_payload_start_seen[tspacket.PID()])
    818     {
    819         if (!tspacket.PayloadStart())
    820             return true; // not payload start - drop packet
    821         VERBOSE(VB_RECORD, LOC + "Found first payload start for " +
    822                 QString("PID 0x%1").arg(tspacket.PID(),0,16));
    823         _payload_start_seen[tspacket.PID()] = true;
    824     }
    825 
    826     // Write out PAT & PMT on occasion...
    827     int pktCnt = _payload_buffer.size() / TSPacket::SIZE;
    828     _ts_packets_until_psip_sync -= (pktCnt + 1);
    829     {
    830         QMutexLocker read_lock(&_pid_lock);
    831         if (_ts_packets_until_psip_sync <= 0 && _pat && _pmt)
    832         {
    833             BufferedWrite(*(reinterpret_cast<TSPacket*>(_pat->tsheader())));
    834             BufferedWrite(*(reinterpret_cast<TSPacket*>(_pmt->tsheader())));
    835             _ts_packets_until_psip_sync = TSPACKETS_BETWEEN_PSIP_SYNC;
    836         }
    837     }
    838 
    839     BufferedWrite(tspacket);
    840 
    841     return true;
    842 }
    843 
    844849#define SEQ_START     0x000001B3
    845850#define GOP_START     0x000001B8
    846851#define PICTURE_START 0x00000100
     
    921926        ringBuffer->Write(buffer, len);
    922927}
    923928
    924 void DVBRecorder::LocalProcessDataTS(const unsigned char *buffer, uint len)
     929void DVBRecorder::LocalProcessDataTS(unsigned char *buffer, int len)
    925930{
     931    QMutexLocker read_lock(&_pid_lock);
     932    if (_ts_packets_until_psip_sync == 0)
     933    {
     934        if (_pat && _pmt)
     935        {
     936            ringBuffer->Write(_pat->tsheader()->data(), TSPacket::SIZE);
     937            ringBuffer->Write(_pmt->tsheader()->data(), TSPacket::SIZE);
     938            _ts_packets_until_psip_sync = TSPACKETS_BETWEEN_PSIP_SYNC;
     939        }
     940    }
     941    else
     942        _ts_packets_until_psip_sync--;
     943
    926944    ringBuffer->Write(buffer,len);
    927945}
    928946
  • libs/libmythtv/dvbrecorder.h

    old new  
    2424
    2525class ProgramAssociationTable;
    2626class ProgramMapTable;
    27 class TSPacket;
    2827
    2928/** \class DVBRecorder
    3029 *  \brief This is a specialization of DTVRecorder used to
     
    6766    void ReadFromDMX(void);
    6867    static void ProcessDataPS(unsigned char *buffer, int len, void *priv);
    6968    void LocalProcessDataPS(unsigned char *buffer, int len);
    70     bool ProcessTSPacket(const TSPacket &tspacket);
    71     void LocalProcessDataTS(const unsigned char *buffer, uint len);
     69    void LocalProcessDataTS(unsigned char *buffer, int len);
    7270
    7371    void CloseFilters(void);
    7472    void OpenFilter(uint pid, ES_Type type, dmx_pes_type_t pes_type,
     
    102100    ProgramAssociationTable *_pat;
    103101    ProgramMapTable         *_pmt;
    104102    uint            _next_pmt_version;
    105     int             _ts_packets_until_psip_sync;
     103    uint            _ts_packets_until_psip_sync;
    106104    QMap<uint,bool> _payload_start_seen;
    107105    QMap<uint,bool> _videoPID;
    108106
     
    129127
    130128    // For debugging
    131129    bool data_found; ///< debugging variable used by transform.c
     130    bool keyframe_found;
    132131
    133132    // Constants
    134133    static const int PMT_PID;
  • libs/libmythtv/firewirerecorder.cpp

    old new  
    1515// MythTV includes
    1616#include "firewirerecorder.h"
    1717#include "mythcontext.h"
     18#include "RingBuffer.h"
    1819#include "tspacket.h"
    1920#include "tv_rec.h"
    2021
    2122// callback function for libiec61883
    22 int read_tspacket (unsigned char *tspacket, int /*len*/,
    23                    uint dropped, void *callback_data)
    24 {
    25     FirewireRecorder *fw = (FirewireRecorder*) callback_data;
     23int read_tspacket (unsigned char *tspacket, int len, unsigned int dropped, void *callback_data) {
    2624
    27     if (!fw)
    28        return 0;
     25     FirewireRecorder *fw = (FirewireRecorder*)callback_data;
     26     if (!fw) return 0;
    2927
    30     if (dropped)
    31     {
    32         VERBOSE(VB_RECORD,
    33                 QString("Firewire: %1 packet(s) dropped.").arg(dropped));
    34     }
    35 
    36     if (SYNC_BYTE != tspacket[0])
    37     {
    38         VERBOSE(VB_IMPORTANT, "Firewire: Got out of sync TS Packet");
    39         return 1;
    40     }
     28     if (dropped) {
     29         VERBOSE(VB_GENERAL,QString("Firewire: %1 packet(s) dropped.").arg(dropped));
     30     }
    4131
    42     fw->ProcessTSPacket(*(reinterpret_cast<TSPacket*>(tspacket)));
     32     if (tspacket[0] == SYNC_BYTE) {
     33         fw->ProcessTSPacket(tspacket,len);
     34     } else {
     35        VERBOSE(VB_GENERAL,QString("Firewire: out of sync mpeg2ts packet"));
     36     }
    4337
    44     return 1;
     38     return 1;
    4539}
    4640
    4741void FirewireRecorder::deleteLater(void)
     
    189183    _recording = false;
    190184
    191185
    192 void FirewireRecorder::ProcessTSPacket(const TSPacket &tspacket)
    193 {
     186void FirewireRecorder::ProcessTSPacket(unsigned char *tspacket, int len) {
     187    tpkt.InitHeader(tspacket);
     188    tpkt.InitPayload(tspacket+4);
     189    FindKeyframes(&tpkt);
    194190    lastpacket = time(NULL);
    195     _buffer_packets = !FindKeyframes(&tspacket);
    196     BufferedWrite(tspacket);
     191    ringBuffer->Write(tspacket,len);
    197192}
    198193
    199194void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
  • libs/libmythtv/firewirerecorder.h

    old new  
    4141
    4242    void StartRecording(void);
    4343    bool Open(void);
    44     void ProcessTSPacket(const TSPacket &tspacket);
     44    void ProcessTSPacket(unsigned char *tspacket, int len);
    4545    void FirewireRecorder::SetOptionsFromProfile(RecordingProfile *profile,
    4646                                         const QString &videodev,
    4747                                         const QString &audiodev,
     
    6666    iec61883_mpeg2_t fwmpeg;
    6767    bool isopen;
    6868    time_t lastpacket;
     69    TSPacket tpkt;
    6970};
    7071
    7172#endif
  • libs/libmythtv/hdtvrecorder.cpp

    old new  
    110110#endif
    111111
    112112HDTVRecorder::HDTVRecorder(TVRec *rec)
    113     : DTVRecorder(rec, "HDTVRecorder"),
    114       _atsc_stream_data(NULL),
    115       _resync_count(0)
     113    : DTVRecorder(rec, "HDTVRecorder"), _atsc_stream_data(0), _resync_count(0)
    116114{
    117115    _atsc_stream_data = new ATSCStreamData(-1, DEFAULT_SUBCHANNEL);
    118116    connect(_atsc_stream_data, SIGNAL(UpdatePATSingleProgram(
     
    689687    return paused;
    690688}
    691689
    692 int HDTVRecorder::ResyncStream(const unsigned char *buffer,
    693                                uint curr_pos, uint len)
     690int HDTVRecorder::ResyncStream(unsigned char *buffer, int curr_pos, int len)
    694691{
    695692    // Search for two sync bytes 188 bytes apart,
    696     uint pos = curr_pos;
    697     uint nextpos = pos + TSPacket::SIZE;
     693    int pos = curr_pos;
     694    int nextpos = pos + TSPacket::SIZE;
    698695    if (nextpos >= len)
    699696        return -1; // not enough bytes; caller should try again
    700697   
    701     while (buffer[pos] != SYNC_BYTE || buffer[nextpos] != SYNC_BYTE)
    702     {
     698    while (buffer[pos] != SYNC_BYTE || buffer[nextpos] != SYNC_BYTE) {
    703699        pos++;
    704700        nextpos++;
    705701        if (nextpos == len)
     
    711707
    712708void HDTVRecorder::WritePAT(ProgramAssociationTable *pat)
    713709{
    714     if (!pat)
    715         return;
    716 
    717710    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf;
    718711    pat->tsheader()->SetContinuityCounter(next);
    719     BufferedWrite(*(reinterpret_cast<TSPacket*>(pat->tsheader())));
     712    ringBuffer->Write(pat->tsheader()->data(), TSPacket::SIZE);
    720713}
    721714
     715#if WHACK_A_BUG_VIDEO
     716static int WABV_base_pid     = 0x100;
     717#define WABV_WAIT 60
     718static int WABV_wait_a_while = WABV_WAIT;
     719bool WABV_started = false;
     720#endif
     721
     722#if WHACK_A_BUG_AUDIO
     723static int WABA_base_pid     = 0x200;
     724#define WABA_WAIT 60
     725static int WABA_wait_a_while = WABA_WAIT;
     726bool WABA_started = false;
     727#endif
     728
    722729void HDTVRecorder::WritePMT(ProgramMapTable* pmt)
    723730{
    724     if (!pmt)
    725         return;
     731    if (pmt) {
     732        int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
     733        pmt->tsheader()->SetContinuityCounter(next);
     734
     735#if WHACK_A_BUG_VIDEO
     736        WABV_wait_a_while--;
     737        if (WABV_wait_a_while<=0) {
     738            WABV_started = true;
     739            WABV_wait_a_while = WABV_WAIT;
     740            WABV_base_pid = (((WABV_base_pid-0x100)+1)%32)+0x100;
     741            if (StreamID::MPEG2Video != StreamData()->PMT()->StreamType(0))
     742            {
     743                VERBOSE(VB_IMPORTANT, "HDTVRecorder::WritePMT(): Error,"
     744                        "Whack a Bug can not rewrite PMT, wrong stream type");
     745            }
     746            else
     747            {
     748                VERBOSE(VB_IMPORTANT, QString("Whack a Bug: new video pid %1").
     749                        arg(WABV_base_pid));
     750                // rewrite video pid
     751                const uint old_video_pid=StreamData()->PMT()->StreamPID(0);
     752                StreamData()->PMT()->SetStreamPID(0, WABV_base_pid);
     753                if (StreamData()->PMT()->PCRPID() == old_video_pid)
     754                    StreamData()->PMT()->SetPCRPID(WABV_base_pid);
     755                StreamData()->PMT()->SetCRC(StreamData()->PMT()->CalcCRC());
     756                VERBOSE(VB_IMPORTANT, StreamData()->PMT()->toString());
     757            }
     758        }
     759#endif
     760#if WHACK_A_BUG_AUDIO
     761        WABA_wait_a_while--;
     762        if (WABA_wait_a_while<=0) {
     763            WABA_started = true;
     764            WABA_wait_a_while = WABA_WAIT;
     765            WABA_base_pid = (((WABA_base_pid-0x200)+1)%32)+0x200;
     766            VERBOSE(VB_IMPORTANT, QString("Whack a Bug: new audio BASE pid %1").arg(WABA_base_pid));
     767            // rewrite audio pids
     768            for (uint i=0; i<StreamData()->PMT()->StreamCount(); i++) {
     769                if (StreamID::MPEG2Audio == StreamData()->PMT()->StreamType(i) ||
     770                    StreamID::MPEG2Audio == StreamData()->PMT()->StreamType(i)) {
     771                    const uint old_audio_pid = StreamData()->PMT()->StreamPID(i);
     772                    const uint new_audio_pid = WABA_base_pid + old_audio_pid;
     773                    StreamData()->PMT()->SetStreamPID(i, new_audio_pid);
     774                    if (StreamData()->PMT()->PCRPID() == old_audio_pid)
     775                        StreamData()->PMT()->SetPCRPID(new_audio_pid);
     776                    StreamData()->PMT()->SetCRC(StreamData()->PMT()->CalcCRC());
     777                    VERBOSE(VB_IMPORTANT, StreamData()->PMT()->toString());
     778                }
     779            }
     780        }
     781#endif
    726782
    727     int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf;
    728     pmt->tsheader()->SetContinuityCounter(next);
    729     BufferedWrite(*(reinterpret_cast<TSPacket*>(pmt->tsheader())));
     783        ringBuffer->Write(pmt->tsheader()->data(), TSPacket::SIZE);
     784    }
    730785}
    731786
    732787/** \fn HDTVRecorder::ProcessMGT(const MasterGuideTable*)
     
    791846    }
    792847}
    793848
    794 bool HDTVRecorder::ProcessTSPacket(const TSPacket &tspacket)
     849void HDTVRecorder::HandleVideo(const TSPacket* tspacket)
     850{
     851    FindKeyframes(tspacket);
     852    // decoder needs video, of course (just this PID)
     853    // delay until first GOP to avoid decoder crash on res change
     854    if (_wait_for_keyframe && !_keyframe_seen)
     855        return;
     856
     857#if WHACK_A_BUG_VIDEO
     858    if (WABV_started)
     859        ((TSPacket*)(tspacket))->SetPID(WABV_base_pid);
     860#endif
     861
     862    ringBuffer->Write(tspacket->data(), TSPacket::SIZE);
     863}
     864
     865void HDTVRecorder::HandleAudio(const TSPacket* tspacket)
     866{
     867    // decoder needs audio, of course (just this PID)
     868    if (_wait_for_keyframe && !_keyframe_seen)
     869        return;
     870
     871#if WHACK_A_BUG_AUDIO
     872    if (WABA_started)
     873        ((TSPacket*)(tspacket))->SetPID(WABA_base_pid+tspacket->PID());
     874#endif
     875
     876    ringBuffer->Write(tspacket->data(), TSPacket::SIZE);
     877}
     878
     879bool HDTVRecorder::ProcessTSPacket(const TSPacket& tspacket)
    795880{
    796881    bool ok = !tspacket.TransportError();
    797882    if (ok && !tspacket.ScramplingControl())
     
    803888            const unsigned int lpid = tspacket.PID();
    804889            // Pass or reject frames based on PID, and parse info from them
    805890            if (lpid == StreamData()->VideoPIDSingleProgram())
    806             {
    807                 _buffer_packets = !FindKeyframes(&tspacket);
    808                 BufferedWrite(tspacket);
    809             }
     891                HandleVideo(&tspacket);
    810892            else if (StreamData()->IsAudioPID(lpid))
    811                 BufferedWrite(tspacket);
     893                HandleAudio(&tspacket);
    812894            else if (StreamData()->IsListeningPID(lpid))
    813895                StreamData()->HandleTSTables(&tspacket);
    814896            else if (StreamData()->IsWritingPID(lpid))
    815                 BufferedWrite(tspacket);
     897                ringBuffer->Write(tspacket.data(), TSPacket::SIZE);
    816898            else if (StreamData()->VersionMGT()>=0)
    817899                _ts_stats.IncrPIDCount(lpid);
    818900        }
     
    820902    return ok;
    821903}
    822904
    823 int HDTVRecorder::ProcessData(const unsigned char *buffer, uint len)
     905int HDTVRecorder::ProcessData(unsigned char *buffer, int len)
    824906{
    825     uint pos = 0;
     907    int pos = 0;
    826908
    827909    while (pos + 187 < len) // while we have a whole packet left
    828910    {
     
    843925        }
    844926
    845927        const TSPacket *pkt = reinterpret_cast<const TSPacket*>(&buffer[pos]);
    846         if (ProcessTSPacket(*pkt))
    847         {
     928        if (ProcessTSPacket(*pkt)) {
    848929            pos += TSPacket::SIZE; // Advance to next TS packet
    849930            _ts_stats.IncrTSPacketCount();
    850931            if (0 == _ts_stats.TSPacketCount()%1000000)
    851932                VERBOSE(VB_RECORD, _ts_stats.toString());
    852         }
    853         else
    854         { // Let it resync in case of dropped bytes
    855             pos++;
    856         }
     933        } else // Let it resync in case of dropped bytes
     934            buffer[pos] = SYNC_BYTE+1;
    857935    }
    858936
    859937    return len - pos;
  • libs/libmythtv/hdtvrecorder.h

    old new  
    6262
    6363  private:
    6464    void TeardownAll(void);
     65    int ProcessData(unsigned char *buffer, int len);
     66    bool ProcessTSPacket(const TSPacket& tspacket);
     67    void HandleVideo(const TSPacket* tspacket);
     68    void HandleAudio(const TSPacket* tspacket);
    6569
    66     int  ProcessData    (const unsigned char *buffer, uint len);
    67     int  ResyncStream   (const unsigned char *buffer, uint pos, uint len);
    68     bool ProcessTSPacket(const TSPacket &tspacket);
     70    int ResyncStream(unsigned char *buffer, int curr_pos, int len);
    6971
    7072    static void *boot_ringbuffer(void *);
    7173    void fill_ringbuffer(void);