Ticket #5443: hdpvr-0.1-recorder.patch

File hdpvr-0.1-recorder.patch, 42.2 KB (added by jppoet@…, 4 years ago)

version 0.1

  • libs/libmythtv/dtvrecorder.h

     
    6565    bool FindH264Keyframes(const TSPacket* tspacket); 
    6666    void HandleH264Keyframe(void); 
    6767 
     68    // PS support (Hauppauge PVR-x50/PVR-500) 
     69    void HandlePSKeyframe(void); 
     70    bool FindPSKeyFrames(unsigned char *buffer, int len); 
     71 
    6872    // For handling other (non audio/video) packets 
    6973    bool FindOtherKeyframes(const TSPacket *tspacket); 
    7074 
     
    111115    unsigned long long _frames_seen_count; 
    112116    unsigned long long _frames_written_count; 
    113117 
     118    int keyframedist; 
     119 
    114120    // constants 
    115121    /// If the number of regular frames detected since the last 
    116122    /// detected keyframe exceeds this value, then we begin marking 
  • libs/libmythtv/dtvrecorder.cpp

     
    1414 
    1515extern "C" { 
    1616// from libavcodec 
    17 extern const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state); 
     17    extern const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state); 
    1818} 
    1919 
    2020#define LOC QString("DTVRec(%1): ").arg(tvrec->GetCaptureCardNum()) 
     
    2727 *         handle MPEG-2, MPEG-4, MPEG-4 AVC, DVB and ATSC streams. 
    2828 * 
    2929 *  \sa DBox2Recorder, DVBRecorder, FirewireRecorder, 
    30         HDHRRecoreder, IPTVRecorder 
    31  */ 
     30 HDHRRecoreder, IPTVRecorder 
     31*/ 
    3232 
    3333DTVRecorder::DTVRecorder(TVRec *rec) :  
    3434    RecorderBase(rec), 
     
    5454    // keyframe TS buffer 
    5555    _buffer_packets(false), 
    5656    // statistics 
    57     _frames_seen_count(0),          _frames_written_count(0) 
     57    _frames_seen_count(0),          _frames_written_count(0), 
     58    keyframedist(15) 
    5859{ 
    5960    SetPositionMapType(MARK_GOP_BYFRAME); 
     61    _payload_buffer.reserve(TSPacket::SIZE * (50 + 1)); 
    6062} 
    6163 
    6264DTVRecorder::~DTVRecorder() 
     
    430432 */ 
    431433bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket) 
    432434{ 
    433     if (!ringBuffer) 
     435    if (!ringBuffer) { 
     436        VERBOSE(VB_IMPORTANT, LOC_ERR + "FindH264Keyframes: No ringbuffer"); 
    434437        return false; 
     438    } 
    435439 
    436440    bool haveBufferedData = !_payload_buffer.empty(); 
    437441    if (!tspacket->HasPayload()) // no payload to scan 
     
    440444    const bool payloadStart = tspacket->PayloadStart(); 
    441445    if (payloadStart) 
    442446    { 
     447        //VERBOSE(VB_RECORD, LOC_ERR + "FindH264Keyframes: payloadStart"); 
    443448        // reset PES sync state 
    444449        _pes_synced = false; 
    445450        _start_code = 0xffffffff; 
     
    459464            if (i + 2 >= TSPacket::SIZE) 
    460465            { 
    461466                VERBOSE(VB_IMPORTANT, LOC_ERR + 
    462                     "PES packet start code may overflow to next TS packet, aborting keyframe search"); 
     467                        "PES packet start code may overflow to next TS " 
     468                        "packet, aborting keyframe search"); 
    463469                break; 
    464470            } 
    465471 
     
    469475                tspacket->data()[i++] != 0x01) 
    470476            { 
    471477                VERBOSE(VB_IMPORTANT, LOC_ERR + 
    472                     "PES start code not found in TS packet with PUSI set"); 
     478                        "PES start code not found in TS packet with PUSI set"); 
    473479                break; 
    474480            } 
    475481 
     
    477483            if (i + 5 >= TSPacket::SIZE) 
    478484            { 
    479485                VERBOSE(VB_IMPORTANT, LOC_ERR + 
    480                     "PES packet headers overflow to next TS packet, aborting keyframe search"); 
     486                        "PES packet headers overflow to next TS packet, " 
     487                        "aborting keyframe search"); 
    481488                break; 
    482489            } 
    483490 
     
    493500            if ((i + 6 + pes_header_length) >= TSPacket::SIZE) 
    494501            { 
    495502                VERBOSE(VB_IMPORTANT, LOC_ERR + 
    496                     "PES packet headers overflow to next TS packet, aborting keyframe search"); 
     503                        "PES packet headers overflow to next TS packet, " 
     504                        "aborting keyframe search"); 
    497505                break; 
    498506            } 
    499507 
    500             // we now know where the PES payload is 
    501             // normally, we should have used 6, but use 5 because the for loop will bump i 
     508            // we now know where the PES payload is. 
     509            // normally, we should have used 6, 
     510            //        but use 5 because the for loop will bump i 
    502511            i += 5 + pes_header_length; 
    503512            _pes_synced = true; 
    504513 
     
    511520            break; 
    512521 
    513522        // scan for a NAL unit start code 
    514         uint32_t bytes_used = _h264_kf_seq.AddBytes(tspacket->data() + i, 
    515                                                    TSPacket::SIZE - i, 
    516                                                    ringBuffer->GetWritePosition()); 
     523        uint32_t bytes_used =  
     524            _h264_kf_seq.AddBytes(tspacket->data() + i, 
     525                                  TSPacket::SIZE - i, 
     526                                  ringBuffer->GetWritePosition()); 
    517527        i += (bytes_used - 1); 
    518528 
    519529        // special handling when we've synced to a NAL unit 
     
    535545 
    536546    if (hasKeyFrame) 
    537547    { 
     548        //VERBOSE(VB_RECORD, LOC_ERR + "FindH264Keyframes: hasKeyFrame"); 
    538549        _last_keyframe_seen = _frames_seen_count; 
    539550        HandleH264Keyframe(); 
    540551    } 
    541552 
    542553    if (hasFrame) 
    543554    { 
     555        //VERBOSE(VB_RECORD, LOC_ERR + "FindH264Keyframes: hasFrame"); 
    544556        _frames_seen_count++; 
    545557        if (!_wait_for_keyframe_option || _first_keyframe >= 0) 
    546558            _frames_written_count++; 
     
    572584    CheckForRingBufferSwitch(); 
    573585} 
    574586 
     587/** \fn DTVRecorder::HandlePSKeyframe(void) 
     588 *  \brief This save the current frame to the position maps 
     589 *         and handles ringbuffer switching. 
     590 */ 
     591void DTVRecorder::HandlePSKeyframe(void) 
     592{ 
     593    if (!ringBuffer) 
     594        return; 
     595 
     596    unsigned long long frameNum = _last_gop_seen; 
     597 
     598    _first_keyframe = (_first_keyframe < 0) ? frameNum : _first_keyframe; 
     599 
     600    // Add key frame to position map 
     601    positionMapLock.lock(); 
     602    if (!positionMap.contains(frameNum)) 
     603    { 
     604        long long startpos = ringBuffer->GetWritePosition(); 
     605        // FIXME: handle keyframes with start code spanning over two ts packets 
     606        startpos += _payload_buffer.size(); 
     607//      VERBOSE(VB_RECORD, LOC + "mpHandleKeyframe frameNum: " << frameNum << ", startpos: " << startpos << " type " << positionMapType << "\n"); 
     608        positionMapDelta[frameNum] = startpos; 
     609        positionMap[frameNum]      = startpos; 
     610    } 
     611    positionMapLock.unlock(); 
     612 
     613    // Perform ringbuffer switch if needed. 
     614    CheckForRingBufferSwitch(); 
     615} 
     616 
     617 
     618bool DTVRecorder::FindPSKeyFrames(unsigned char *buffer, int len) 
     619{ 
     620    unsigned char *bufptr = buffer, *bufstart = buffer; 
     621    uint v = 0; 
     622    int leftlen = len; 
     623    bool hasKeyFrame = false; 
     624 
     625    while (bufptr < buffer + len) 
     626    { 
     627        v = *bufptr++; 
     628        if (_start_code == 0x000001) 
     629        { 
     630            _start_code = ((_start_code << 8) | v) & 0xFFFFFF; 
     631            const int stream_id = _start_code & 0x000000ff; 
     632 
     633            if (stream_id == PESStreamID::PackHeader) 
     634            { 
     635                _last_keyframe_seen = ringBuffer->GetWritePosition() + 
     636                                      _payload_buffer.size(); 
     637 
     638                int curpos = bufptr - bufstart - 4; 
     639                if (curpos < 0) 
     640                { 
     641                    // header was split 
     642                    if (_payload_buffer.size() + curpos > 0) 
     643                        ringBuffer->Write(&_payload_buffer[0], 
     644                                          _payload_buffer.size() + curpos); 
     645 
     646                    _payload_buffer.resize(4); 
     647                    memcpy(&_payload_buffer[0], &_start_code, 4); 
     648 
     649                    leftlen = leftlen - curpos + 4; 
     650                    bufstart = bufptr; 
     651                } 
     652                else 
     653                { 
     654                    // header was entirely in this packet 
     655                    int idx = _payload_buffer.size(); 
     656                    _payload_buffer.resize(idx + curpos); 
     657                    memcpy(&_payload_buffer[idx], bufstart, curpos); 
     658 
     659                    bufstart += curpos; 
     660                    leftlen -= curpos; 
     661 
     662                    if (_payload_buffer.size() > 0) 
     663                        ringBuffer->Write(&_payload_buffer[0], 
     664                                          _payload_buffer.size()); 
     665                    _payload_buffer.clear(); 
     666                } 
     667                _frames_seen_count++; 
     668            } 
     669            else if (stream_id == PESStreamID::SequenceStartCode) 
     670            { 
     671                _last_seq_seen = _last_keyframe_seen; 
     672            } 
     673            else if (stream_id == PESStreamID::GOPStartCode && 
     674                     _last_seq_seen == _last_keyframe_seen) 
     675            { 
     676                _frames_written_count = _last_gop_seen * keyframedist; 
     677                _last_gop_seen++; 
     678                HandlePSKeyframe(); 
     679            } 
     680        } 
     681        else 
     682            _start_code = ((_start_code << 8) | v) & 0xFFFFFF; 
     683    } 
     684 
     685    int idx = _payload_buffer.size(); 
     686    _payload_buffer.resize(idx + leftlen); 
     687    memcpy(&_payload_buffer[idx], bufstart, leftlen); 
     688 
     689    return hasKeyFrame; 
     690} 
     691 
     692 
    575693/* vim: set expandtab tabstop=4 shiftwidth=4: */ 
  • libs/libmythtv/mpegrecorder.h

     
    33#ifndef MPEGRECORDER_H_ 
    44#define MPEGRECORDER_H_ 
    55 
    6 #include "recorderbase.h" 
     6#include "dtvrecorder.h" 
     7#include "tspacket.h" 
     8#include "mpegstreamdata.h" 
    79 
    810struct AVFormatContext; 
    911struct AVPacket; 
    1012 
    11 class MpegRecorder : public RecorderBase 
     13class MpegRecorder : public DTVRecorder, 
     14                     public MPEGSingleProgramStreamListener 
    1215{ 
    1316  public: 
    1417    MpegRecorder(TVRec*); 
     
    3336    bool PauseAndWait(int timeout = 100); 
    3437 
    3538    bool IsRecording(void) { return recording; } 
    36     bool IsErrored(void) { return errored; } 
    3739 
    38     long long GetFramesWritten(void) { return framesWritten; } 
    39  
    4040    bool Open(void); 
    4141    int GetVideoFd(void) { return chanfd; } 
    4242 
    43     long long GetKeyframePosition(long long desired); 
     43    // TS 
     44    virtual void SetStreamData(MPEGStreamData*); 
     45    virtual MPEGStreamData *GetStreamData(void) { return _stream_data; } 
    4446 
    45     void SetNextRecording(const ProgramInfo*, RingBuffer*); 
     47    // implements MPEGSingleProgramStreamListener 
     48    void HandleSingleProgramPAT(ProgramAssociationTable *pat); 
     49    void HandleSingleProgramPMT(ProgramMapTable *pmt); 
    4650 
    4751  private: 
    48     bool SetupRecording(void); 
    49     void FinishRecording(void); 
    50     void HandleKeyframe(void); 
    51  
    5252    void ProcessData(unsigned char *buffer, int len); 
    5353 
    5454    bool OpenMpegFileAsInput(void); 
     
    6060    uint GetFilteredAudioSampleRate(void) const; 
    6161    uint GetFilteredAudioLayer(void) const; 
    6262    uint GetFilteredAudioBitRate(uint audio_layer) const; 
     63    void ProcessPSdata(unsigned char *buffer, int len); 
     64    void ProcessTSdata(unsigned char * data, int len, uint & leftover); 
     65    void ProcessTSPacket(const TSPacket &tspacket); 
    6366 
    6467    void ResetForNewFile(void); 
    6568 
     
    7881    // State 
    7982    bool recording; 
    8083    bool encoding; 
    81     bool errored; 
    8284 
    8385    // Pausing state 
    8486    bool cleartimeonpause; 
    8587 
    86     // Number of frames written 
    87     long long framesWritten; 
    88  
    8988    // Encoding info 
    9089    int width, height; 
    9190    int bitrate, maxbitrate, streamtype, aspectratio; 
     
    9796    int chanfd; 
    9897    int readfd; 
    9998 
    100     // Keyframe tracking inforamtion 
    101     int keyframedist; 
    102     bool gopset; 
    103     unsigned int leftovers; 
    104     long long lastpackheaderpos; 
    105     long long lastseqstart; 
    106     long long numgops; 
    107  
    108     // buffer used for ... 
    109     unsigned char *buildbuffer; 
    110     unsigned int buildbuffersize; 
    111  
    11299    static const int   audRateL1[]; 
    113100    static const int   audRateL2[]; 
    114101    static const int   audRateL3[]; 
    115102    static const char *streamType[]; 
    116103    static const char *aspectRatio[]; 
    117104    static const unsigned int kBuildBufferMaxSize; 
     105 
     106    // TS 
     107    MPEGStreamData *_stream_data; 
    118108}; 
    119109#endif 
  • libs/libmythtv/cardutil.cpp

     
    14731473{ 
    14741474    bool ok; 
    14751475    QStringList ret; 
     1476 
    14761477    int videofd = open(device.ascii(), O_RDWR); 
    14771478    if (videofd < 0) 
    14781479    { 
     
    14801481                           "to probe its inputs.").arg(device); 
    14811482        return ret; 
    14821483    } 
     1484 
    14831485    InputNames list = CardUtil::probeV4LInputs(videofd, ok); 
    14841486    close(videofd); 
    14851487 
  • libs/libmythtv/mpegrecorder.cpp

     
    4848const int MpegRecorder::audRateL1[] = 
    4949{ 
    5050    32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 
    51 }; 
     51        }; 
    5252 
    5353const int MpegRecorder::audRateL2[] = 
    5454{ 
     
    7373    "Square", "4:3", "16:9", "2.21:1", 0 
    7474}; 
    7575 
    76 const unsigned int MpegRecorder::kBuildBufferMaxSize = 1024 * 1024; 
    77  
    78 MpegRecorder::MpegRecorder(TVRec *rec) : 
    79     RecorderBase(rec), 
     76MpegRecorder::MpegRecorder(TVRec *rec) : DTVRecorder(rec), 
    8077    // Debugging variables 
    8178    deviceIsMpegFile(false), 
    82     bufferSize(4096), 
    8379    // Driver info 
    8480    card(QString::null),      driver(QString::null), 
    8581    version(0),               usingv4l2(false), 
     
    8783    requires_special_pause(false), 
    8884    // State 
    8985    recording(false),         encoding(false), 
    90     errored(false), 
    9186    // Pausing state 
    9287    cleartimeonpause(false), 
    93     // Number of frames written 
    94     framesWritten(0), 
    9588    // Encoding info 
    9689    width(720),               height(480), 
    9790    bitrate(4500),            maxbitrate(6000), 
     
    10295    audvolume(80),            language(0), 
    10396    // Input file descriptors 
    10497    chanfd(-1),               readfd(-1), 
    105     // Keyframe tracking inforamtion 
    106     keyframedist(15),         gopset(false), 
    107     leftovers(0),             lastpackheaderpos(0), 
    108     lastseqstart(0),          numgops(0), 
    109     // buffer used for ... 
    110     buildbuffer(new unsigned char[kBuildBufferMaxSize + 1]), 
    111     buildbuffersize(0) 
     98    // TS packet handling 
     99    _stream_data(NULL)                                    
    112100{ 
    113101    SetPositionMapType(MARK_GOP_START); 
    114102} 
     
    116104MpegRecorder::~MpegRecorder() 
    117105{ 
    118106    TeardownAll(); 
    119     delete [] buildbuffer; 
    120107} 
    121108 
    122109void MpegRecorder::TeardownAll(void) 
     
    332319 
    333320    if (CardUtil::GetV4LInfo(chanfd, card, driver, version)) 
    334321    { 
     322//      driver = "hdpvr"; 
     323 
    335324        if (driver == "ivtv") 
    336325        { 
     326            bufferSize = 4096; 
     327 
    337328            usingv4l2     = (version >= IVTV_KERNEL_VERSION(0, 8, 0)); 
    338329            has_v4l2_vbi  = (version >= IVTV_KERNEL_VERSION(0, 3, 8)); 
    339330            has_buggy_vbi = true; 
    340331            requires_special_pause = 
    341332                (version >= IVTV_KERNEL_VERSION(0, 10, 0)); 
    342333        } 
     334        else if (driver == "hdpvr") 
     335        { 
     336            bufferSize = 1500 * TSPacket::SIZE; 
     337            usingv4l2 = true; 
     338        } 
    343339        else 
    344340        { 
    345             VERBOSE(VB_IMPORTANT, "\n\nNot ivtv driver??\n\n"); 
     341            VERBOSE(VB_IMPORTANT, "\n\nNot ivtv or hdpvr driver??\n\n"); 
    346342            usingv4l2 = has_v4l2_vbi = true; 
    347343            has_buggy_vbi = requires_special_pause = false; 
    348344        } 
     
    354350 
    355351    struct v4l2_format vfmt; 
    356352    bzero(&vfmt, sizeof(vfmt)); 
    357  
     353     
    358354    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 
    359  
     355     
    360356    if (ioctl(chanfd, VIDIOC_G_FMT, &vfmt) < 0) 
    361357    { 
    362358        VERBOSE(VB_IMPORTANT, LOC_ERR + "Error getting format" + ENO); 
    363359        return false; 
    364360    } 
     361         
     362    if (driver != "hdpvr") { 
     363        vfmt.fmt.pix.width = width; 
     364        vfmt.fmt.pix.height = height; 
     365         
     366        if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0) 
     367        { 
     368            VERBOSE(VB_IMPORTANT, LOC_ERR + "Error setting format" + ENO); 
     369            return false; 
     370        } 
    365371 
    366     vfmt.fmt.pix.width = width; 
    367     vfmt.fmt.pix.height = height; 
    368  
    369     if (ioctl(chanfd, VIDIOC_S_FMT, &vfmt) < 0) 
    370     { 
    371         VERBOSE(VB_IMPORTANT, LOC_ERR + "Error setting format" + ENO); 
    372         return false; 
    373     } 
    374  
    375     // Set audio language mode 
    376     bool do_audmode_set = true; 
    377     struct v4l2_tuner vt; 
    378     bzero(&vt, sizeof(struct v4l2_tuner)); 
    379     if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0) 
    380     { 
    381         VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get audio mode" + ENO); 
    382         do_audmode_set = false; 
    383     } 
    384  
    385     switch (language) 
    386     { 
    387         case 0: 
     372        // Set audio language mode 
     373        bool do_audmode_set = true; 
     374        struct v4l2_tuner vt; 
     375        bzero(&vt, sizeof(struct v4l2_tuner)); 
     376        if (ioctl(chanfd, VIDIOC_G_TUNER, &vt) < 0) 
     377        { 
     378            VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get audio mode" + ENO); 
     379            do_audmode_set = false; 
     380        } 
     381         
     382        switch (language) 
     383        { 
     384          case 0: 
    388385            vt.audmode = V4L2_TUNER_MODE_LANG1; 
    389386            break; 
    390         case 1: 
     387          case 1: 
    391388            vt.audmode = V4L2_TUNER_MODE_LANG2; 
    392389            break; 
    393         case 2: 
     390          case 2: 
    394391            if (usingv4l2) 
    395392                vt.audmode = V4L2_TUNER_MODE_LANG1_LANG2; 
    396393            else 
    397394                vt.audmode = V4L2_TUNER_MODE_STEREO; 
    398395            break; 
    399         default: 
     396          default: 
    400397            vt.audmode = V4L2_TUNER_MODE_LANG1; 
    401     } 
     398        } 
    402399 
    403     int audio_layer = GetFilteredAudioLayer(); 
    404     if (do_audmode_set && (2 == language) && (1 == audio_layer)) 
    405     { 
    406         VERBOSE(VB_GENERAL, "Dual audio mode incompatible with Layer I audio." 
    407                 "\n\t\t\tFalling back to Main Language"); 
    408         vt.audmode = V4L2_TUNER_MODE_LANG1; 
    409     } 
     400        int audio_layer = GetFilteredAudioLayer(); 
     401        if (do_audmode_set && (2 == language) && (1 == audio_layer)) 
     402        { 
     403            VERBOSE(VB_GENERAL, "Dual audio mode incompatible with Layer I audio." 
     404                    "\n\t\t\tFalling back to Main Language"); 
     405            vt.audmode = V4L2_TUNER_MODE_LANG1; 
     406        } 
    410407 
    411     if (do_audmode_set && ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0) 
    412     { 
    413         VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to set audio mode" + ENO); 
    414     } 
     408        if (do_audmode_set && ioctl(chanfd, VIDIOC_S_TUNER, &vt) < 0) 
     409        { 
     410            VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to set audio mode" + ENO); 
     411        } 
    415412 
    416     // Get volume min/max values 
    417     struct v4l2_queryctrl qctrl; 
    418     qctrl.id = V4L2_CID_AUDIO_VOLUME; 
    419     if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) 
    420     { 
    421         VERBOSE(VB_IMPORTANT, LOC_WARN + 
    422                 "Unable to get recording volume parameters(max/min)" + ENO + 
    423                 "\n\t\t\tusing default range [0,65535]."); 
    424         qctrl.maximum = 65535; 
    425         qctrl.minimum = 0; 
    426     } 
     413        // Get volume min/max values 
     414        struct v4l2_queryctrl qctrl; 
     415        qctrl.id = V4L2_CID_AUDIO_VOLUME; 
     416        if (ioctl(chanfd, VIDIOC_QUERYCTRL, &qctrl) < 0) 
     417        { 
     418            VERBOSE(VB_IMPORTANT, LOC_WARN + 
     419                    "Unable to get recording volume parameters(max/min)" + ENO + 
     420                    "\n\t\t\tusing default range [0,65535]."); 
     421            qctrl.maximum = 65535; 
     422            qctrl.minimum = 0; 
     423        } 
    427424 
    428     // calculate volume in card units. 
    429     int range = qctrl.maximum - qctrl.minimum; 
    430     int value = (int) ((range * audvolume * 0.01f) + qctrl.minimum); 
    431     int ctrl_volume = min(qctrl.maximum, max(qctrl.minimum, value)); 
     425        // calculate volume in card units. 
     426        int range = qctrl.maximum - qctrl.minimum; 
     427        int value = (int) ((range * audvolume * 0.01f) + qctrl.minimum); 
     428        int ctrl_volume = min(qctrl.maximum, max(qctrl.minimum, value)); 
    432429 
    433     // Set recording volume 
    434     struct v4l2_control ctrl; 
    435     ctrl.id = V4L2_CID_AUDIO_VOLUME; 
    436     ctrl.value = ctrl_volume; 
     430        // Set recording volume 
     431        struct v4l2_control ctrl; 
     432        ctrl.id = V4L2_CID_AUDIO_VOLUME; 
     433        ctrl.value = ctrl_volume; 
    437434 
    438     if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0) 
    439     { 
    440         VERBOSE(VB_IMPORTANT, LOC_WARN + 
    441                 "Unable to set recording volume" + ENO + "\n\t\t\t" + 
    442                 "If you are using an AverMedia M179 card this is normal."); 
     435        if (ioctl(chanfd, VIDIOC_S_CTRL, &ctrl) < 0) 
     436        { 
     437            VERBOSE(VB_IMPORTANT, LOC_WARN + 
     438                    "Unable to set recording volume" + ENO + "\n\t\t\t" + 
     439                    "If you are using an AverMedia M179 card this is normal."); 
     440        } 
    443441    } 
    444442 
    445443    bool ok = true; 
     
    457455 
    458456    SetVBIOptions(chanfd); 
    459457 
    460     readfd = open(videodevice.ascii(), O_RDWR | O_NONBLOCK); 
     458    // hdpvr driver does not like NONBLOCK mode with select 
     459    if (driver == "hdpvr") 
     460        readfd = open(videodevice.ascii(), O_RDWR); 
     461    else 
     462        readfd = open(videodevice.ascii(), O_RDWR | O_NONBLOCK); 
     463 
    461464    if (readfd < 0) 
    462465    { 
    463466        VERBOSE(VB_IMPORTANT, LOC_ERR + "Can't open video device." + ENO); 
     
    475478    { 
    476479        switch (st) 
    477480        { 
    478             case 2:  st = 2;  break; 
    479             case 10: 
    480             case 13: 
    481             case 14: st = 10; break; 
    482             case 11: st = 11; break; 
    483             case 12: st = 12; break; 
    484             default: st = 0;  break;    
     481          case 2:  st = 2;  break; 
     482          case 10: 
     483          case 13: 
     484          case 14: st = 10; break; 
     485          case 11: st = 11; break; 
     486          case 12: st = 12; break; 
     487          default: st = 0;  break;    
    485488        } 
    486489    } 
     490    else if (driver == "hdpvr") 
     491    { 
     492        // FIX ME!  // I have no idea what to put here 
     493        switch (st) 
     494        { 
     495          case 2:  st = 2;  break; 
     496          case 10: 
     497          case 13: 
     498          case 14: st = 10; break; 
     499          case 11: st = 11; break; 
     500          case 12: st = 12; break; 
     501          default: st = 0;  break;    
     502        } 
     503    } 
    487504 
    488505    if (st != (uint) streamtype) 
    489506    { 
     
    502519 
    503520    sr = (driver == "ivtv") ? 48000 : sr; // only 48kHz works properly. 
    504521 
     522    // hdpvr ? 
     523 
     524 
    505525    if (sr != (uint) audsamplerate) 
    506526    { 
    507527        VERBOSE(VB_IMPORTANT, LOC_WARN + 
     
    512532 
    513533    switch (sr) 
    514534    { 
    515         case 32000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000; 
    516         case 44100: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100; 
    517         case 48000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; 
    518         default:    return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; 
     535      case 32000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000; 
     536      case 44100: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100; 
     537      case 48000: return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; 
     538      default:    return V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000; 
    519539    } 
    520540} 
    521541 
     
    527547 
    528548    layer = (driver == "ivtv") ? 2 : layer; 
    529549 
     550    // hdpvr? 
     551 
     552 
    530553    if (layer != (uint) audtype) 
    531554    { 
    532555        VERBOSE(VB_IMPORTANT, LOC_WARN + 
     
    587610{ 
    588611    switch (st) 
    589612    { 
    590         case 0:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS; 
    591         case 1:  return V4L2_MPEG_STREAM_TYPE_MPEG2_TS; 
    592         case 2:  return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD; 
    593         case 3:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES A/V    */ 
    594         case 5:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES V      */ 
    595         case 7:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES A      */ 
    596         case 10: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; 
    597         case 11: return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD; /* VCD */ 
    598         case 12: return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD; 
    599         case 13: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 1 */ 
    600         case 14: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 2 */ 
    601         default: return V4L2_MPEG_STREAM_TYPE_MPEG2_TS; 
     613      case 0:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS; 
     614      case 1:  return V4L2_MPEG_STREAM_TYPE_MPEG2_TS; 
     615      case 2:  return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD; 
     616      case 3:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES A/V    */ 
     617      case 5:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES V      */ 
     618      case 7:  return V4L2_MPEG_STREAM_TYPE_MPEG2_PS;  /* PES A      */ 
     619      case 10: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; 
     620      case 11: return V4L2_MPEG_STREAM_TYPE_MPEG1_VCD; /* VCD */ 
     621      case 12: return V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD; 
     622      case 13: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 1 */ 
     623      case 14: return V4L2_MPEG_STREAM_TYPE_MPEG2_DVD; /* DVD-Special 2 */ 
     624      default: return V4L2_MPEG_STREAM_TYPE_MPEG2_TS; 
    602625    } 
    603626} 
    604627 
    605628bool MpegRecorder::SetV4L2DeviceOptions(int chanfd) 
    606629{ 
    607     static const uint kNumControls = 7; 
     630   static const uint kNumControls = 7; 
    608631    struct v4l2_ext_controls ctrls; 
    609632    struct v4l2_ext_control ext_ctrl[kNumControls]; 
    610633    QString control_description[kNumControls] = 
     
    625648    uint audio_layer = GetFilteredAudioLayer(); 
    626649    uint audbitrate  = GetFilteredAudioBitRate(audio_layer); 
    627650 
    628     ext_ctrl[0].id    = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; 
    629     ext_ctrl[0].value = GetFilteredAudioSampleRate(); 
     651    if (driver != "hdpvr") { 
     652        ext_ctrl[0].id    = V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ; 
     653        ext_ctrl[0].value = GetFilteredAudioSampleRate(); 
     654         
     655        ext_ctrl[1].id    = V4L2_CID_MPEG_VIDEO_ASPECT; 
     656        ext_ctrl[1].value = aspectratio - 1; 
     657         
     658        ext_ctrl[2].id    = V4L2_CID_MPEG_AUDIO_ENCODING; 
     659        ext_ctrl[2].value = audio_layer - 1; 
     660         
     661        ext_ctrl[3].id    = V4L2_CID_MPEG_AUDIO_L2_BITRATE; 
     662        ext_ctrl[3].value = audbitrate - 1; 
    630663 
    631     ext_ctrl[1].id    = V4L2_CID_MPEG_VIDEO_ASPECT; 
    632     ext_ctrl[1].value = aspectratio - 1; 
     664        ext_ctrl[4].id    = V4L2_CID_MPEG_STREAM_TYPE; 
     665        ext_ctrl[4].value = streamtype_ivtv_to_v4l2(GetFilteredStreamType()); 
     666    } 
    633667 
    634     ext_ctrl[2].id    = V4L2_CID_MPEG_AUDIO_ENCODING; 
    635     ext_ctrl[2].value = audio_layer - 1; 
     668    ext_ctrl[5].id    = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK; 
     669    ext_ctrl[5].value = maxbitrate * 1000; 
    636670 
    637     ext_ctrl[3].id    = V4L2_CID_MPEG_AUDIO_L2_BITRATE; 
    638     ext_ctrl[3].value = audbitrate - 1; 
     671    ext_ctrl[6].id    = V4L2_CID_MPEG_VIDEO_BITRATE; 
     672    ext_ctrl[6].value = (bitrate = min(bitrate, maxbitrate)) * 1000; 
    639673 
    640     ext_ctrl[4].id    = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK; 
    641     ext_ctrl[4].value = maxbitrate * 1000; 
    642  
    643     ext_ctrl[5].id    = V4L2_CID_MPEG_VIDEO_BITRATE; 
    644     ext_ctrl[5].value = (bitrate = min(bitrate, maxbitrate)) * 1000; 
    645  
    646     ext_ctrl[6].id    = V4L2_CID_MPEG_STREAM_TYPE; 
    647     ext_ctrl[6].value = streamtype_ivtv_to_v4l2(GetFilteredStreamType()); 
    648  
    649674    for (uint i = 0; i < kNumControls; i++) 
    650675    { 
    651676        int value = ext_ctrl[i].value; 
    652677 
     678        if (value != 0) { 
     679            ctrls.ctrl_class  = V4L2_CTRL_CLASS_MPEG; 
     680            ctrls.count       = 1; 
     681            ctrls.controls    = ext_ctrl + i; 
     682             
     683            if (ioctl(chanfd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) 
     684            { 
     685                VERBOSE(VB_IMPORTANT, LOC_ERR + 
     686                        QString("Could not set %1 to %2") 
     687                        .arg(control_description[i]).arg(value) + ENO); 
     688            } 
     689        } 
     690    } 
     691 
     692    if (driver != "hdpvr") { 
     693        // Get controls 
     694        ext_ctrl[0].id    = V4L2_CID_MPEG_VIDEO_GOP_SIZE; 
     695        ext_ctrl[0].value = 0; 
     696         
    653697        ctrls.ctrl_class  = V4L2_CTRL_CLASS_MPEG; 
    654698        ctrls.count       = 1; 
    655         ctrls.controls    = ext_ctrl + i; 
    656  
    657         if (ioctl(chanfd, VIDIOC_S_EXT_CTRLS, &ctrls) < 0) 
     699        ctrls.controls    = ext_ctrl; 
     700         
     701        if (ioctl(chanfd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0) 
    658702        { 
    659             VERBOSE(VB_IMPORTANT, LOC_ERR + 
    660                     QString("Could not set %1 to %2") 
    661                     .arg(control_description[i]).arg(value) + ENO); 
     703            VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get " 
     704                    "V4L2_CID_MPEG_VIDEO_GOP_SIZE, defaulting to 12" + ENO); 
     705            ext_ctrl[0].value = 12; 
    662706        } 
     707         
     708        keyframedist = ext_ctrl[0].value; 
    663709    } 
    664710 
    665     // Get controls 
    666     ext_ctrl[0].id    = V4L2_CID_MPEG_VIDEO_GOP_SIZE; 
    667     ext_ctrl[0].value = 0; 
    668  
    669     ctrls.ctrl_class  = V4L2_CTRL_CLASS_MPEG; 
    670     ctrls.count       = 1; 
    671     ctrls.controls    = ext_ctrl; 
    672  
    673     if (ioctl(chanfd, VIDIOC_G_EXT_CTRLS, &ctrls) < 0) 
    674     { 
    675         VERBOSE(VB_IMPORTANT, LOC_WARN + "Unable to get " 
    676                 "V4L2_CID_MPEG_VIDEO_GOP_SIZE, defaulting to 12" + ENO); 
    677         ext_ctrl[0].value = 12; 
    678     } 
    679  
    680     keyframedist = ext_ctrl[0].value; 
    681  
    682711    return true; 
    683712} 
    684713 
     
    687716    if (!vbimode) 
    688717        return true; 
    689718 
     719    if (driver == "hdpvr") 
     720        return true; 
     721 
    690722    if (has_buggy_vbi) 
    691723    { 
    692724        cout<<" *********************** WARNING ***********************"<<endl; 
     
    717749 
    718750        if (ioctl(chanfd, IVTV_IOC_G_VBI_MODE, &vbifmt) >= 0) 
    719751        { 
    720             VERBOSE(VB_RECORD, LOC + QString( 
    721                         "VBI service:%1, packet size:%2, io size:%3") 
     752            VERBOSE(VB_RECORD, 
     753                    LOC + QString("VBI service:%1, packet size:%2, io size:%3") 
    722754                    .arg(vbifmt.service_set).arg(vbifmt.packet_size) 
    723755                    .arg(vbifmt.io_size)); 
    724756        } 
     
    733765        bzero(&vbifmt, sizeof(struct v4l2_format)); 
    734766        vbifmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 
    735767        vbifmt.fmt.sliced.service_set |= (1 == vbimode) ? 
    736             V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 
     768               V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 
    737769 
    738770        if (ioctl(chanfd, VIDIOC_S_FMT, &vbifmt) < 0) 
    739771        { 
     
    809841{ 
    810842    if (!Open()) 
    811843    { 
    812         errored = true; 
    813         return; 
     844        _error = true; 
     845        return; 
    814846    } 
    815847 
    816     if (!SetupRecording()) 
    817     { 
    818         VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to setup recording."); 
    819         errored = true; 
    820         return; 
     848    _start_code = 0xffffffff; 
     849    _last_gop_seen = 0; 
     850    _frames_written_count = 0; 
     851 
     852    if (driver == "hdpvr") { 
     853        SetPositionMapType(MARK_GOP_BYFRAME); 
     854 
     855        if (_stream_data == NULL) { 
     856            int progNum = 1; 
     857            MPEGStreamData *sd = new MPEGStreamData(progNum, true); 
     858            sd->SetCaching(true); 
     859            SetStreamData(sd); 
     860        } 
    821861    } 
     862    else { 
     863        SetPositionMapType(MARK_GOP_START); 
     864    } 
    822865 
    823866    encoding = true; 
    824867    recording = true; 
    825     unsigned char *buffer = new unsigned char[bufferSize + 1]; 
     868 
     869    // Add an extra TSPacket::SIZE for "leftover_bytes" 
     870    unsigned char *buffer = new unsigned char[bufferSize + TSPacket::SIZE + 1]; 
     871    unsigned char *bufstart = &buffer[TSPacket::SIZE]; 
     872    uint leftover_bytes = 0; 
     873 
    826874    int ret; 
    827875 
    828876    MythTimer elapsedTimer; 
     
    839887        if (PauseAndWait(100)) 
    840888            continue; 
    841889 
    842         if ((deviceIsMpegFile) && (framesWritten)) 
     890        if ((deviceIsMpegFile) && (GetFramesWritten())) 
    843891        { 
    844892            elapsed = (elapsedTimer.elapsed() / 1000.0) + 1; 
    845             while ((framesWritten / elapsed) > 30) 
     893            while ((GetFramesWritten() / elapsed) > 30) 
    846894            { 
    847895                usleep(50000); 
    848896                elapsed = (elapsedTimer.elapsed() / 1000.0) + 1; 
     
    852900        if (readfd < 0) 
    853901            readfd = open(videodevice.ascii(), O_RDWR); 
    854902 
    855         tv.tv_sec = 5; 
    856         tv.tv_usec = 0; 
    857         FD_ZERO(&rdset); 
    858         FD_SET(readfd, &rdset); 
    859  
    860903#if defined(__FreeBSD__) 
    861904        // HACK. FreeBSD PVR150/500 driver doesn't currently support select() 
    862905#else 
    863         switch (select(readfd + 1, &rdset, NULL, NULL, &tv)) 
    864         { 
    865             case -1: 
     906        // hdpvr driver does not like NONBLOCK mode with select 
     907        if (driver != "hdpvr") { 
     908            tv.tv_sec = 5; 
     909            tv.tv_usec = 0; 
     910            FD_ZERO(&rdset); 
     911            FD_SET(readfd, &rdset); 
     912 
     913            switch (select(readfd + 1, &rdset, NULL, NULL, &tv)) 
     914            { 
     915              case -1: 
    866916                if (errno == EINTR) 
    867917                    continue; 
    868  
     918                 
    869919                VERBOSE(VB_IMPORTANT, LOC_ERR + "Select error" + ENO); 
    870920                continue; 
    871  
    872             case 0: 
     921                 
     922              case 0: 
    873923                VERBOSE(VB_IMPORTANT, LOC_ERR + "select timeout - " 
    874924                        "ivtv driver has stopped responding"); 
    875  
     925                 
    876926                if (close(readfd) != 0) 
    877927                { 
    878928                    VERBOSE(VB_IMPORTANT, LOC_ERR + "Close error" + ENO); 
    879929                } 
    880  
     930                 
    881931                readfd = -1; // Force PVR card to be reopened on next iteration 
    882932                continue; 
    883  
    884            default: break; 
     933                 
     934              default: break; 
     935            } 
    885936        } 
    886937#endif 
    887938 
    888         ret = read(readfd, buffer, bufferSize); 
     939        ret = read(readfd, bufstart, bufferSize); 
    889940 
    890         if ((ret == 0) && 
    891             (deviceIsMpegFile)) 
     941        if ((ret == 0) && (deviceIsMpegFile)) 
    892942        { 
    893943            close(readfd); 
    894944            readfd = open(videodevice.ascii(), O_RDONLY); 
    895945 
    896946            if (readfd >= 0) 
    897                 ret = read(readfd, buffer, bufferSize); 
     947                ret = read(readfd, bufstart, bufferSize); 
    898948            if (ret <= 0) 
    899949            { 
    900950                encoding = false; 
     
    905955        { 
    906956            VERBOSE(VB_IMPORTANT, LOC_ERR + QString("error reading from: %1") 
    907957                    .arg(videodevice) + ENO); 
    908  
    909958            continue; 
    910959        } 
    911960        else if (ret > 0) 
    912961        { 
    913             ProcessData(buffer, ret); 
     962            if (driver == "hdpvr") 
     963                ProcessTSdata(buffer, ret, leftover_bytes); 
     964            else 
     965                ProcessPSdata(bufstart, ret); 
    914966        } 
    915967    } 
    916968 
     
    920972    recording = false; 
    921973} 
    922974 
    923 bool MpegRecorder::SetupRecording(void) 
     975void MpegRecorder::ProcessPSdata(unsigned char *buffer, int len) 
    924976{ 
    925     leftovers = 0xFFFFFFFF; 
    926     numgops = 0; 
    927     lastseqstart = 0; 
    928     return true; 
     977    FindPSKeyFrames(buffer, len); 
    929978} 
    930979 
    931 void MpegRecorder::FinishRecording(void) 
     980void MpegRecorder::ProcessTSdata(unsigned char * data, int len, uint & leftover) 
    932981{ 
    933     ringBuffer->WriterFlush(); 
     982    uint idx, pos; 
     983    uint last = TSPacket::SIZE + leftover + len; 
    934984 
    935     if (curRecording) 
    936     { 
    937         curRecording->SetFilesize(ringBuffer->GetRealFileSize()); 
    938         SavePositionMap(true); 
    939     } 
    940     positionMapLock.lock(); 
    941     positionMap.clear(); 
    942     positionMapDelta.clear(); 
    943     positionMapLock.unlock(); 
    944 } 
     985    for (idx = TSPacket::SIZE - leftover; idx < last; ) { 
     986        // Find header 
     987        for (pos = idx; pos < last; ++pos) { 
     988            if (data[pos] == SYNC_BYTE ) 
     989                break; 
     990        } 
    945991 
    946 #define PACK_HEADER   0x000001BA 
    947 #define GOP_START     0x000001B8 
    948 #define SEQ_START     0x000001B3 
    949 #define SLICE_MIN     0x00000101 
    950 #define SLICE_MAX     0x000001af 
     992        if (pos == last) { 
     993            VERBOSE(VB_IMPORTANT, LOC_ERR + "No TS header."); 
     994            break; 
     995        } 
    951996 
    952 void MpegRecorder::ProcessData(unsigned char *buffer, int len) 
    953 { 
    954     unsigned char *bufptr = buffer, *bufstart = buffer; 
    955     unsigned int state = leftovers, v = 0; 
    956     int leftlen = len; 
     997        if (pos > idx) { 
     998            VERBOSE(VB_IMPORTANT, LOC_ERR + 
     999                    QString("TS packet at %1 not in sync.").arg(pos)); 
     1000        } 
    9571001 
    958     while (bufptr < buffer + len) 
    959     { 
    960         v = *bufptr++; 
    961         if (state == 0x000001) 
    962         { 
    963             state = ((state << 8) | v) & 0xFFFFFF; 
    964              
    965             if (state == PACK_HEADER) 
    966             { 
    967                 long long startpos = ringBuffer->GetWritePosition(); 
    968                 startpos += buildbuffersize + bufptr - bufstart - 4; 
    969                 lastpackheaderpos = startpos; 
     1002        if ((last - pos) < TSPacket::SIZE) { 
     1003            VERBOSE(VB_RECORD, LOC_ERR + 
     1004                    QString("TS packet at %1 stradles end of buffer.") 
     1005                    .arg(pos)); 
     1006            leftover = last - pos; 
     1007            memmove(&data[TSPacket::SIZE - leftover], &data[pos], leftover); 
     1008            return; 
     1009        } 
    9701010 
    971                 int curpos = bufptr - bufstart - 4; 
    972                 if (curpos < 0) 
    973                 { 
    974                     // header was split 
    975                     buildbuffersize += curpos; 
    976                     if (buildbuffersize > 0) 
    977                         ringBuffer->Write(buildbuffer, buildbuffersize); 
     1011        ProcessTSPacket(* reinterpret_cast<const TSPacket *>(data + pos)); 
    9781012 
    979                     buildbuffersize = 4; 
    980                     memcpy(buildbuffer, &state, 4); 
     1013        // Next packet 
     1014        idx = pos + TSPacket::SIZE; 
     1015    } 
    9811016 
    982                     leftlen = leftlen - curpos + 4; 
    983                     bufstart = bufptr; 
    984                 } 
    985                 else 
    986                 { 
    987                     // header was entirely in this packet 
    988                     memcpy(buildbuffer + buildbuffersize, bufstart, curpos); 
    989                     buildbuffersize += curpos; 
    990                     bufstart += curpos; 
    991                     leftlen -= curpos; 
     1017    leftover = 0; 
     1018    return; 
     1019} 
    9921020 
    993                     if (buildbuffersize > 0) 
    994                         ringBuffer->Write(buildbuffer, buildbuffersize); 
     1021void MpegRecorder::ProcessTSPacket(const TSPacket &tspacket) 
     1022{ 
     1023    if (!_stream_data) 
     1024        return; 
    9951025 
    996                     buildbuffersize = 0; 
    997                 } 
    998             } 
     1026    if (tspacket.TransportError() || tspacket.ScramplingControl()) 
     1027        return; 
    9991028 
    1000             if (state == SEQ_START) 
    1001             { 
    1002                 lastseqstart = lastpackheaderpos; 
    1003             } 
     1029    if (tspacket.HasAdaptationField()) 
     1030        _stream_data->HandleAdaptationFieldControl(&tspacket); 
    10041031 
    1005             if (state == GOP_START && lastseqstart == lastpackheaderpos) 
    1006             { 
    1007                 framesWritten = numgops * keyframedist; 
    1008                 numgops++; 
    1009                 HandleKeyframe(); 
    1010             } 
    1011         } 
    1012         else 
    1013             state = ((state << 8) | v) & 0xFFFFFF; 
    1014     } 
     1032    if (tspacket.HasPayload()) 
     1033    { 
     1034        const unsigned int lpid = tspacket.PID(); 
    10151035 
    1016     leftovers = state; 
     1036        // Pass or reject packets based on PID, and parse info from them 
     1037//        if (lpid == _stream_data->VideoPIDSingleProgram()) 
     1038        if (lpid == 4113) 
     1039        { 
     1040            _buffer_packets = !FindH264Keyframes(&tspacket); 
    10171041 
    1018     if (buildbuffersize + leftlen > kBuildBufferMaxSize) 
    1019     { 
    1020         ringBuffer->Write(buildbuffer, buildbuffersize); 
    1021         buildbuffersize = 0; 
     1042            if (_seen_sps) 
     1043                BufferedWrite(tspacket);             
     1044        } 
     1045//        else if (_stream_data->IsAudioPID(lpid)) 
     1046        else if (lpid == 4352) 
     1047        { 
     1048            _buffer_packets = !FindAudioKeyframes(&tspacket); 
     1049            BufferedWrite(tspacket); 
     1050        } 
     1051        else { 
     1052            BufferedWrite(tspacket); 
     1053        } 
    10221054    } 
    1023  
    1024     // copy remaining.. 
    1025     memcpy(buildbuffer + buildbuffersize, bufstart, leftlen); 
    1026     buildbuffersize += leftlen; 
    10271055} 
    10281056 
    10291057void MpegRecorder::StopRecording(void) 
     
    10331061 
    10341062void MpegRecorder::ResetForNewFile(void) 
    10351063{ 
    1036     errored = false; 
    1037     framesWritten = 0; 
    1038     numgops = 0; 
    1039     lastseqstart = lastpackheaderpos = 0; 
     1064    DTVRecorder::ResetForNewFile(); 
    10401065 
    1041     positionMap.clear(); 
    1042     positionMapDelta.clear(); 
    10431066} 
    10441067 
    10451068void MpegRecorder::Reset(void) 
    10461069{ 
     1070    VERBOSE(VB_RECORD, LOC + "Reset(void)"); 
    10471071    ResetForNewFile(); 
    10481072 
    1049     leftovers = 0xFFFFFFFF; 
    1050     buildbuffersize = 0; 
     1073    _start_code = 0xffffffff; 
    10511074 
    1052     if (curRecording) 
    1053         curRecording->ClearPositionMap(MARK_GOP_START); 
     1075    if (curRecording) { 
     1076        if (driver == "hdpvr") { 
     1077            curRecording->ClearPositionMap(MARK_GOP_BYFRAME); 
     1078        } 
     1079        else { 
     1080            curRecording->ClearPositionMap(MARK_GOP_START); 
     1081        } 
     1082    } 
    10541083} 
    10551084 
    10561085void MpegRecorder::Pause(bool clear) 
     
    10951124                command.cmd = V4L2_ENC_CMD_START; 
    10961125                ioctl(readfd, VIDIOC_ENCODER_CMD, &command); 
    10971126            } 
     1127 
     1128            if (_stream_data) 
     1129                _stream_data->Reset(_stream_data->DesiredProgram()); 
    10981130        } 
    10991131        paused = false; 
    11001132    } 
    11011133    return paused; 
    11021134} 
    11031135 
    1104 long long MpegRecorder::GetKeyframePosition(long long desired) 
     1136void MpegRecorder::SetStreamData(MPEGStreamData *data) 
    11051137{ 
    1106     QMutexLocker locker(&positionMapLock); 
    1107     long long ret = -1; 
     1138    VERBOSE(VB_RECORD, LOC + "SetStreamData("<<data<<") -- begin"); 
    11081139 
    1109     if (positionMap.find(desired) != positionMap.end()) 
    1110         ret = positionMap[desired]; 
     1140    if (data == _stream_data) 
     1141    { 
     1142        VERBOSE(VB_RECORD, LOC + "SetStreamData("<<data<<") -- end 0"); 
    11111143 
    1112     return ret; 
     1144        return; 
     1145    } 
     1146 
     1147    MPEGStreamData *old_data = _stream_data; 
     1148    _stream_data = data; 
     1149    if (old_data) 
     1150        delete old_data; 
     1151 
     1152    if (data) 
     1153        data->AddMPEGSPListener(this); 
     1154 
     1155    VERBOSE(VB_RECORD, LOC + "SetStreamData("<<data<<") -- end 1"); 
    11131156} 
    11141157 
    1115 // documented in recorderbase.h 
    1116 void MpegRecorder::SetNextRecording(const ProgramInfo *progInf, RingBuffer *rb) 
     1158void MpegRecorder::HandleSingleProgramPAT(ProgramAssociationTable *pat) 
    11171159{ 
    1118     // First we do some of the time consuming stuff we can do now 
    1119     SavePositionMap(true); 
    1120     ringBuffer->WriterFlush(); 
    1121         if (curRecording) 
    1122         curRecording->SetFilesize(ringBuffer->GetRealFileSize()); 
     1160    if (!pat) 
     1161        return; 
    11231162 
    1124     // Then we set the next info 
    1125     { 
    1126         QMutexLocker locker(&nextRingBufferLock); 
    1127         nextRecording = NULL; 
    1128         if (progInf) 
    1129             nextRecording = new ProgramInfo(*progInf); 
    1130         nextRingBuffer = rb; 
    1131     } 
     1163    int next = (pat->tsheader()->ContinuityCounter()+1)&0xf; 
     1164    pat->tsheader()->SetContinuityCounter(next); 
     1165    BufferedWrite(*(reinterpret_cast<const TSPacket*>(pat->tsheader()))); 
    11321166} 
    11331167 
    1134 /** \fn MpegRecorder::HandleKeyframe(void) 
    1135  *  \brief This save the current frame to the position maps 
    1136  *         and handles ringbuffer switching. 
    1137  */ 
    1138 void MpegRecorder::HandleKeyframe(void) 
     1168void MpegRecorder::HandleSingleProgramPMT(ProgramMapTable *pmt) 
    11391169{ 
    1140     // Add key frame to position map 
    1141     positionMapLock.lock(); 
    1142     if (!positionMap.contains(numgops)) 
    1143     { 
    1144         positionMapDelta[numgops] = lastpackheaderpos; 
    1145         positionMap[numgops]      = lastpackheaderpos; 
    1146     } 
    1147     positionMapLock.unlock(); 
     1170    if (!pmt) 
     1171        return; 
    11481172 
    1149     // Perform ringbuffer switch if needed. 
    1150     CheckForRingBufferSwitch(); 
     1173    int next = (pmt->tsheader()->ContinuityCounter()+1)&0xf; 
     1174    pmt->tsheader()->SetContinuityCounter(next); 
     1175    BufferedWrite(*(reinterpret_cast<const TSPacket*>(pmt->tsheader()))); 
    11511176} 
    1152