Ticket #10101: 20181222_eitpf-timing.patch

File 20181222_eitpf-timing.patch, 10.0 KB (added by Klaas de Waal, 5 years ago)
  • mythtv/libs/libmythtv/recorders/dtvrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
    index 8d3c7b9579..40a608e0b3 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) : 
    7778    // record 'raw' mpts?
    7879    _record_mpts(0),
    7980    _record_mpts_only(false),
     81    // EIT timing
     82    _is_running(false),
     83    _is_following(false),
    8084    // statistics
    8185    _use_pts(false),
    8286    _packet_count(0),
    RecordingQuality *DTVRecorder::GetRecordingQuality(const RecordingInfo *r) const 
    16251629    return recq;
    16261630}
    16271631
     1632void DTVRecorder::HandleEIT(const DVBEventInformationTable *eit)
     1633{
     1634    DVBStreamData *dsd = dynamic_cast<DVBStreamData*>(_stream_data);
     1635    if (dsd &&
     1636        TableID::PF_EIT == eit->TableID() &&
     1637        eit->ServiceID() == (uint) dsd->DesiredProgram() &&
     1638        eit->OriginalNetworkID() == dsd->DesiredNetworkID() &&
     1639        eit->TSID() == dsd->DesiredTransportID())
     1640    {
     1641        for (uint i = 0; i < eit->EventCount(); i++)
     1642        {
     1643            QString programId, recordingProgId, recordingTitle;
     1644            desc_list_t list = MPEGDescriptor::Parse(
     1645                eit->Descriptors(i), eit->DescriptorsLength(i));
     1646            desc_list_t contentIds =
     1647                MPEGDescriptor::FindAll(list, DescriptorID::dvb_content_identifier);
     1648            for (uint j = 0; j < contentIds.size(); j++)
     1649            {
     1650                DVBContentIdentifierDescriptor desc(contentIds[j]);
     1651                if (desc.ContentEncoding() == 0 &&
     1652                    (desc.ContentType() == 0x01 || desc.ContentType() == 0x31))
     1653                {
     1654                    programId = desc.ContentId();
     1655                }
     1656            }
     1657
     1658            if (curRecording)
     1659            {
     1660                recordingProgId = curRecording->GetProgramID();
     1661                recordingTitle = curRecording->GetTitle();
     1662            }
     1663            // The programid in curRecording will have the default authority at the start
     1664            // so we have a match if they end the same.
     1665            bool isMatch = false;
     1666            if (!programId.isEmpty() && !recordingProgId.isEmpty())
     1667                isMatch = recordingProgId.endsWith(programId.toLower());
     1668            else
     1669            {
     1670                // Fall back to matching on the title.
     1671                desc_list_t shortEvents =
     1672                    MPEGDescriptor::FindAll(list, DescriptorID::short_event);
     1673                for (uint j = 0; j < shortEvents.size(); j++)
     1674                {
     1675                    ShortEventDescriptor sed(shortEvents[j]);
     1676                    // The title may include a subtitle that has been removed
     1677                    // by a fixup.
     1678                    if (sed.EventName().startsWith(recordingTitle))
     1679                    {
     1680                        isMatch = true;
     1681                        break;
     1682                    }
     1683                }
     1684            }
     1685
     1686            if (eit->Section() == 0)
     1687            {
     1688                LOG(VB_GENERAL, LOG_INFO, LOC + QString("Current is now %1").arg(programId));
     1689                _is_running = isMatch;
     1690            }
     1691            else if (eit->Section() == 1)
     1692            {
     1693                LOG(VB_GENERAL, LOG_INFO, LOC + QString("Following is now %1").arg(programId));
     1694                _is_following = isMatch;
     1695            }
     1696            if (curRecording)
     1697            {
     1698                LOG(VB_GENERAL, LOG_INFO,
     1699                    LOC + QString("Recording for %1 (%2) running=%3, following=%4")
     1700                    .arg(curRecording->GetTitle()).arg(recordingProgId)
     1701                    .arg(_is_running).arg(_is_following));
     1702            }
     1703        }
     1704    }
     1705}
     1706
    16281707/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythtv/libs/libmythtv/recorders/dtvrecorder.h

    diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.h b/mythtv/libs/libmythtv/recorders/dtvrecorder.h
    index 6874edbd54..14849f58b5 100644
    a b class DTVRecorder : 
    3333    public ATSCMainStreamListener,
    3434    public TSPacketListener,
    3535    public TSPacketListenerAV,
     36    public DVBEITStreamListener,
    3637    public PSStreamListener
    3738{
    3839  public:
    class DTVRecorder : 
    9394    // Common audio/visual processing
    9495    bool ProcessAVTSPacket(const TSPacket &tspacket);
    9596
     97    // EIT timing information
     98    bool IsRunning(void) { return _is_running; }
     99    bool IsFollowing(void) { return _is_following; }
     100
    96101  protected:
    97102    virtual void InitStreamData(void);
    98103
    class DTVRecorder : 
    127132    virtual void SetCAMPMT(const ProgramMapTable*) {}
    128133    virtual void UpdateCAMTimeOffset(void) {}
    129134
     135    void HandleEIT(const DVBEventInformationTable*) override;
     136    void HandleEIT(const PremiereContentInformationTable*) override {}
     137
    130138    // file handle for stream
    131139    int _stream_fd;
    132140
    class DTVRecorder : 
    181189    unsigned char _continuity_counter[0x1fff + 1];
    182190    vector<TSPacket> _scratch;
    183191
     192    // EIT timing
     193    bool _is_running;
     194    bool _is_following;
     195
    184196    // Statistics
    185197    int           _minimum_recording_quality;
    186198    bool          _use_pts; // vs use dts
  • mythtv/libs/libmythtv/recorders/dvbrecorder.cpp

    diff --git a/mythtv/libs/libmythtv/recorders/dvbrecorder.cpp b/mythtv/libs/libmythtv/recorders/dvbrecorder.cpp
    index fac5b4a76a..9e86c1e224 100644
    a b  
    2424// MythTV includes
    2525#include "dvbstreamhandler.h"
    2626#include "mpegstreamdata.h"
     27#include "dvbstreamdata.h"
    2728#include "tsstreamdata.h"
    2829#include "dvbrecorder.h"
    2930#include "dvbchannel.h"
    void DVBRecorder::run(void) 
    119120    if (_record_mpts_only)
    120121        _stream_data->AddListeningPID(0x2000);
    121122
     123    DVBStreamData *dsd = dynamic_cast<DVBStreamData*>(_stream_data);
     124    if (dsd)
     125        dsd->AddDVBEITListener(this);
     126
    122127    StartNewFile();
    123128
    124129    _stream_data->AddAVListener(this);
    void DVBRecorder::run(void) 
    126131    _stream_handler->AddListener(_stream_data, false, true,
    127132                         (_record_mpts) ? ringBuffer->GetFilename() : QString());
    128133
     134    QString recordingProgId = QString("?");
     135    QString recordingTitle = QString("?");
     136    if (curRecording)
     137    {
     138        recordingProgId = curRecording->GetProgramID();
     139        recordingTitle = curRecording->GetTitle();
     140    }
     141    LOG(VB_GENERAL, LOG_INFO, LOC + QString("Recording %1 (%2) service %3 net %4 transport %5")
     142        .arg(recordingTitle).arg(recordingProgId).arg(dsd->DesiredProgram())
     143        .arg(dsd->DesiredNetworkID()).arg(dsd->DesiredTransportID()));
     144
    129145    while (IsRecordingRequested() && !IsErrored())
    130146    {
    131147        if (PauseAndWait())
    void DVBRecorder::run(void) 
    158174    _stream_data->RemoveWritingListener(this);
    159175    _stream_data->RemoveAVListener(this);
    160176
     177    if (dsd)
     178        dsd->RemoveDVBEITListener(this);
     179
    161180    Close();
    162181
    163182    FinishRecording();
  • mythtv/libs/libmythtv/tv_rec.cpp

    diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp
    index 421aff6823..52d5fb4fc3 100644
    a b TVRec::TVRec(int _inputid) 
    116116      // Current recording info
    117117      curRecording(nullptr),
    118118      overrecordseconds(0),
     119      eitIsRunning(false),
     120      eitIsFollowing(false),
    119121      // Pseudo LiveTV recording
    120122      pseudoLiveTVRecording(nullptr),
    121123      nextLiveTVDir(""),            nextLiveTVDirLock(),
    void TVRec::run(void) 
    13471349        // Tell frontends about pending recordings
    13481350        HandlePendingRecordings();
    13491351
     1352        bool isRunning = false;
     1353        bool isFollowing = false;
     1354        if (GetDTVRecorder())
     1355        {
     1356            isRunning = GetDTVRecorder()->IsRunning();
     1357            isFollowing = GetDTVRecorder()->IsFollowing();
     1358        }
     1359        if (isRunning && eitIsFollowing && ! eitIsRunning)
     1360        {
     1361            // Set a bookmark at the transition from Following to Present.
     1362            if (curRecording)
     1363                curRecording->SaveBookmark(GetFramesWritten());
     1364        }
     1365        eitIsRunning = isRunning;
     1366        eitIsFollowing = isFollowing;
     1367
    13501368        // If we are recording a program, check if the recording is
    13511369        // over or someone has asked us to finish the recording.
    13521370        // Add an extra 60 seconds to the recording end time if we
    void TVRec::run(void) 
    13541372        QDateTime recEnd = (!pendingRecordings.empty()) ?
    13551373            recordEndTime.addSecs(60) : recordEndTime;
    13561374        if ((GetState() == kState_RecordingOnly) &&
    1357             (MythDate::current() > recEnd ||
     1375            ((MythDate::current() > recEnd && !isRunning) ||
    13581376             HasFlags(kFlagFinishRecording)))
    13591377        {
     1378            QDateTime actualTime = QDateTime::currentDateTime();
     1379            QString title;
     1380            if (curRecording)
     1381                title = curRecording->GetTitle();
     1382            if (actualTime > recordEndTime.addSecs(10))
     1383                LOG(VB_GENERAL, LOG_INFO,
     1384                    QString("Extended end time of recording of %1 from %2 to %3")
     1385                        .arg(title)
     1386                        .arg(recordEndTime.toString("hh:mm:ss"))
     1387                        .arg(actualTime.toString("hh:mm:ss")));
     1388
    13601389            ChangeState(kState_None);
    13611390            ClearFlags(kFlagFinishRecording, __FILE__, __LINE__);
    13621391        }
  • mythtv/libs/libmythtv/tv_rec.h

    diff --git a/mythtv/libs/libmythtv/tv_rec.h b/mythtv/libs/libmythtv/tv_rec.h
    index 3d8321a339..0acd4536b8 100644
    a b class MTV_PUBLIC TVRec : public SignalMonitorListener, public QRunnable 
    410410    QDateTime    recordEndTime;
    411411    QHash<QString,int> autoRunJobs; // RecordingInfo::MakeUniqueKey()->autoRun
    412412    int          overrecordseconds;
     413    bool         eitIsRunning;
     414    bool         eitIsFollowing;
    413415
    414416    // Pending recording info
    415417    PendingMap   pendingRecordings;