Ticket #10101: eitpf-timing.patch

File eitpf-timing.patch, 10.3 KB (added by David Matthews <dm@…>, 13 years ago)
  • mythtv/libs/libmythtv/dtvrecorder.cpp

    commit 877b6008fa700713c697eb9043d63119f9398c07
    Author: David Matthews <dm@prolingua.co.uk>
    Date:   Fri Oct 14 16:57:26 2011 +0100
    
        Recording timing from EITpf
        
        This patch adds code to monitor EITpf.  It sets a bookmark when the programme to be recorded changes from
        "following" to "present" and extends the recording period if a programme is still "present" when the
        scheduled recording time has been reached.
    
    diff --git a/mythtv/libs/libmythtv/dtvrecorder.cpp b/mythtv/libs/libmythtv/dtvrecorder.cpp
    index e0a5335..1781a55 100644
    a b  
    2121#include "atscstreamdata.h"
    2222#include "mpegstreamdata.h"
    2323#include "dvbstreamdata.h"
     24#include "dvbtables.h"
    2425#include "dtvrecorder.h"
    2526#include "programinfo.h"
    2627#include "mythlogging.h"
    DTVRecorder::DTVRecorder(TVRec *rec) : 
    7273    _input_pat(NULL),
    7374    _input_pmt(NULL),
    7475    _has_no_av(false),
     76    // EIT timing
     77    _is_running(false),
     78    _is_following(false),
    7579    // statistics
    7680    _packet_count(0),
    7781    _continuity_error_count(0),
    bool DTVRecorder::ProcessAVTSPacket(const TSPacket &tspacket) 
    11821186    return true;
    11831187}
    11841188
     1189void DTVRecorder::HandleEIT(const DVBEventInformationTable *eit)
     1190{
     1191    DVBStreamData *dsd = dynamic_cast<DVBStreamData*>(_stream_data);
     1192    if (dsd &&
     1193        TableID::PF_EIT == eit->TableID() &&
     1194        eit->ServiceID() == dsd->DesiredProgram() &&
     1195        eit->OriginalNetworkID() == dsd->DesiredNetworkID() &&
     1196        eit->TSID() == dsd->DesiredTransportID())
     1197    {
     1198        for (uint i = 0; i < eit->EventCount(); i++)
     1199        {
     1200            QString programId, recordingProgId, recordingTitle;
     1201            desc_list_t list = MPEGDescriptor::Parse(
     1202                eit->Descriptors(i), eit->DescriptorsLength(i));
     1203            desc_list_t contentIds =
     1204                MPEGDescriptor::FindAll(list, DescriptorID::dvb_content_identifier);
     1205            for (uint j = 0; j < contentIds.size(); j++)
     1206            {
     1207                DVBContentIdentifierDescriptor desc(contentIds[j]);
     1208                if (desc.ContentEncoding() == 0 &&
     1209                    (desc.ContentType() == 0x01 || desc.ContentType() == 0x31))
     1210                {
     1211                    programId = desc.ContentId();
     1212                }
     1213            }
     1214
     1215            if (curRecording)
     1216            {
     1217                recordingProgId = curRecording->GetProgramID();
     1218                recordingTitle = curRecording->GetTitle();
     1219            }
     1220            // The programid in curRecording will have the default authority at the start
     1221            // so we have a match if they end the same.
     1222            bool isMatch = false;
     1223            if (!programId.isEmpty() && !recordingProgId.isEmpty())
     1224                isMatch = recordingProgId.endsWith(programId.toLower());
     1225            else
     1226            {
     1227                // Fall back to matching on the title.
     1228                desc_list_t shortEvents =
     1229                    MPEGDescriptor::FindAll(list, DescriptorID::short_event);
     1230                for (uint j = 0; j < shortEvents.size(); j++)
     1231                {
     1232                    ShortEventDescriptor sed(shortEvents[j]);
     1233                    // The title may include a subtitle that has been removed
     1234                    // by a fixup.
     1235                    if (sed.EventName().startsWith(recordingTitle))
     1236                    {
     1237                        isMatch = true;
     1238                        break;
     1239                    }
     1240                }
     1241            }
     1242
     1243            if (eit->Section() == 0)
     1244            {
     1245                LOG(VB_GENERAL, LOG_INFO, LOC + QString("Current is now %1").arg(programId));
     1246                _is_running = isMatch;
     1247            }
     1248            else if (eit->Section() == 1)
     1249            {
     1250                LOG(VB_GENERAL, LOG_INFO, LOC + QString("Following is now %1").arg(programId));
     1251                _is_following = isMatch;
     1252            }
     1253            if (curRecording)
     1254            {
     1255                LOG(VB_GENERAL, LOG_INFO,
     1256                    LOC + QString("Recording for %1 (%2) running=%3, following=%4")
     1257                    .arg(curRecording->GetTitle()).arg(recordingProgId)
     1258                    .arg(_is_running).arg(_is_following));
     1259            }
     1260        }
     1261    }
     1262}
     1263
    11851264/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythtv/libs/libmythtv/dtvrecorder.h

    diff --git a/mythtv/libs/libmythtv/dtvrecorder.h b/mythtv/libs/libmythtv/dtvrecorder.h
    index 25b8c7e..f103b17 100644
    a b class DTVRecorder : 
    2929    public DVBMainStreamListener,
    3030    public ATSCMainStreamListener,
    3131    public TSPacketListener,
    32     public TSPacketListenerAV
     32    public TSPacketListenerAV,
     33    public DVBEITStreamListener
    3334{
    3435  public:
    3536    DTVRecorder(TVRec *rec);
    class DTVRecorder : 
    8687    // Common audio/visual processing
    8788    bool ProcessAVTSPacket(const TSPacket &tspacket);
    8889
     90    // EIT timing information
     91    bool IsRunning(void) { return _is_running; }
     92    bool IsFollowing(void) { return _is_following; }
     93
    8994  protected:
    9095    void FinishRecording(void);
    9196    void ResetForNewFile(void);
    class DTVRecorder : 
    116121    virtual void SetCAMPMT(const ProgramMapTable*) {}
    117122    virtual void UpdateCAMTimeOffset(void) {}
    118123
     124    void HandleEIT(const DVBEventInformationTable*);
     125    void HandleEIT(const PremiereContentInformationTable*) {}
     126
    119127    // file handle for stream
    120128    int _stream_fd;
    121129
    class DTVRecorder : 
    164172    unsigned char _continuity_counter[0x1fff + 1];
    165173    vector<TSPacket> _scratch;
    166174
     175    // EIT timing
     176    bool _is_running, _is_following;
     177
    167178    // Statistics
    168179    mutable unsigned long long _packet_count;
    169180    mutable unsigned long long _continuity_error_count;
  • mythtv/libs/libmythtv/dvbrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/dvbrecorder.cpp b/mythtv/libs/libmythtv/dvbrecorder.cpp
    index e842e32..d4257f9 100644
    a b  
    2424// MythTV includes
    2525#include "dvbstreamhandler.h"
    2626#include "mpegstreamdata.h"
     27#include "dvbstreamdata.h"
    2728#include "dvbrecorder.h"
    2829#include "dvbchannel.h"
    2930#include "tv_rec.h"
    void DVBRecorder::run(void) 
    9697    if (_channel && (_channel->GetSIStandard() == "dvb"))
    9798        _stream_data->AddListeningPID(DVB_TDT_PID);
    9899
     100    DVBStreamData *dsd = dynamic_cast<DVBStreamData*>(_stream_data);
     101    if (dsd)
     102        dsd->AddDVBEITListener(this);
     103
    99104    // Make sure the first things in the file are a PAT & PMT
    100105    bool tmp = _wait_for_keyframe_option;
    101106    _wait_for_keyframe_option = false;
    void DVBRecorder::run(void) 
    107112    _stream_data->AddWritingListener(this);
    108113    _stream_handler->AddListener(_stream_data, false, true);
    109114
     115    QString recordingProgId = QString("?"), recordingTitle = QString("?");
     116    if (curRecording)
     117    {
     118        recordingProgId = curRecording->GetProgramID();
     119        recordingTitle = curRecording->GetTitle();
     120    }
     121    LOG(VB_GENERAL, LOG_INFO, LOC + QString("Recording %1 (%2) service %3 net %4 transport %5")
     122        .arg(recordingTitle).arg(recordingProgId).arg(dsd->DesiredProgram())
     123        .arg(dsd->DesiredNetworkID()).arg(dsd->DesiredTransportID()));
     124
    110125    while (IsRecordingRequested() && !IsErrored())
    111126    {
    112127        if (PauseAndWait())
    void DVBRecorder::run(void) 
    139154    _stream_data->RemoveWritingListener(this);
    140155    _stream_data->RemoveAVListener(this);
    141156
     157    if (dsd)
     158        dsd->RemoveDVBEITListener(this);
     159
    142160    Close();
    143161
    144162    FinishRecording();
  • mythtv/libs/libmythtv/tv_rec.cpp

    diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp
    index 2eedf68..7011091 100644
    a b TVRec::TVRec(int capturecardnum) 
    109109      // Current recording info
    110110      curRecording(NULL), autoRunJobs(JOB_NONE),
    111111      overrecordseconds(0),
     112      eitIsRunning(false), eitIsFollowing(false),
    112113      // Pseudo LiveTV recording
    113114      pseudoLiveTVRecording(NULL),
    114115      nextLiveTVDir(""),            nextLiveTVDirLock(),
    void TVRec::run(void) 
    12211222        // Tell frontends about pending recordings
    12221223        HandlePendingRecordings();
    12231224
     1225        bool isRunning = false, isFollowing = false;
     1226        if (GetDTVRecorder())
     1227        {
     1228            isRunning = GetDTVRecorder()->IsRunning();
     1229            isFollowing = GetDTVRecorder()->IsFollowing();
     1230        }
     1231        if (isRunning && eitIsFollowing && ! eitIsRunning)
     1232        {
     1233            // Set a bookmark at the transition from Following to Present.
     1234            if (curRecording)
     1235                curRecording->SaveBookmark(GetFramesWritten());
     1236        }
     1237        eitIsRunning = isRunning;
     1238        eitIsFollowing = isFollowing;
     1239
    12241240        // If we are recording a program, check if the recording is
    12251241        // over or someone has asked us to finish the recording.
    12261242        // Add an extra 60 seconds to the recording end time if we
    void TVRec::run(void) 
    12281244        QDateTime recEnd = (!pendingRecordings.empty()) ?
    12291245            recordEndTime.addSecs(60) : recordEndTime;
    12301246        if ((GetState() == kState_RecordingOnly) &&
    1231             (QDateTime::currentDateTime() > recEnd ||
     1247            ((QDateTime::currentDateTime() > recEnd && !isRunning) ||
    12321248             HasFlags(kFlagFinishRecording)))
    12331249        {
     1250            QDateTime actualTime = QDateTime::currentDateTime();
     1251            QString title;
     1252            if (curRecording)
     1253                title = curRecording->GetTitle();
     1254            if (actualTime > recordEndTime.addSecs(10))
     1255                LOG(VB_GENERAL, LOG_INFO,
     1256                    QString("Extended end time of recording of %1 from %2 to %3")
     1257                        .arg(title)
     1258                        .arg(recordEndTime.toString("hh:mm:ss"))
     1259                        .arg(actualTime.toString("hh:mm:ss")));
     1260
    12341261            ChangeState(kState_None);
    12351262            ClearFlags(kFlagFinishRecording);
    12361263        }
  • mythtv/libs/libmythtv/tv_rec.h

    diff --git a/mythtv/libs/libmythtv/tv_rec.h b/mythtv/libs/libmythtv/tv_rec.h
    index e867271..59b3d65 100644
    a b class MTV_PUBLIC TVRec : public SignalMonitorListener, public QRunnable 
    369369    QDateTime    recordEndTime;
    370370    int          autoRunJobs;
    371371    int          overrecordseconds;
     372    bool         eitIsRunning, eitIsFollowing;
    372373
    373374    // Pending recording info
    374375    PendingMap   pendingRecordings;