Ticket #11098: mythtv_remove_code_duplication_in_mpeg_table_accounting.patch

File mythtv_remove_code_duplication_in_mpeg_table_accounting.patch, 40.0 KB (added by Rune Petersen <rune@…>, 12 years ago)
  • mythtv/libs/libmythtv/libmythtv.pro

    diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro
    index c815431..528cb08 100644
    a b HEADERS += mpeg/freesat_huffman.h mpeg/freesat_tables.h 
    183183HEADERS += mpeg/iso6937tables.h
    184184HEADERS += mpeg/tsstats.h           mpeg/streamlisteners.h
    185185HEADERS += mpeg/H264Parser.h
     186HEADERS += mpeg/TableStatus.h
    186187
    187188SOURCES += mpeg/tspacket.cpp        mpeg/pespacket.cpp
    188189SOURCES += mpeg/mpegtables.cpp      mpeg/atsctables.cpp
    SOURCES += mpeg/atsc_huffman.cpp 
    198199SOURCES += mpeg/freesat_huffman.cpp
    199200SOURCES += mpeg/iso6937tables.cpp
    200201SOURCES += mpeg/H264Parser.cpp
     202SOURCES += mpeg/TableStatus.cpp
    201203
    202204# Channels, and the multiplexes that transmit them
    203205HEADERS += frequencies.h            frequencytables.h
  • new file mythtv/libs/libmythtv/mpeg/TableStatus.cpp

    diff --git a/mythtv/libs/libmythtv/mpeg/TableStatus.cpp b/mythtv/libs/libmythtv/mpeg/TableStatus.cpp
    new file mode 100644
    index 0000000..5990b80
    - +  
     1// -*- Mode: c++ -*-
     2// Copyright (c) 2003-2012
     3
     4#include "TableStatus.h"
     5
     6#define BIT_SEL(x) (1<(x))
     7
     8void TableStatus::InitSections(sections_t &sect, uint32_t last_section)
     9{
     10    static const unsigned char init_bits[8] =
     11        { 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, };
     12
     13    sect.clear();
     14
     15    uint endz = last_section >> 3;
     16    if (endz)
     17        sect.resize(endz, 0x00);
     18    sect.resize(32, 0xff);
     19    sect[endz] = init_bits[last_section & 0x7];
     20
     21#if 0
     22    {
     23        QString msg = QString("init_sections ls(%1): ").arg(last_section);
     24        for (uint i = 0 ; i < 32; i++)
     25            msg += QString("%1 ").arg((int)sect[i], 0, 16);
     26        LOG(VB_GENERAL, LOG_DEBUG, msg);
     27    }
     28#endif
     29}
     30void TableStatus::SetVersion(int32_t version, uint32_t last_section)
     31{
     32    if (m_version == version)
     33        return;
     34
     35    m_version = version;
     36    InitSections(m_sections, last_section);
     37}
     38
     39void TableStatus::SetSectionSeen(int32_t version, uint32_t section, uint32_t last_section)
     40{
     41    SetVersion(version, last_section);
     42    m_sections[section>>3] |= BIT_SEL(section & 0x7);
     43}
     44
     45bool TableStatus::IsSectionSeen(int32_t version, uint32_t section) const
     46{
     47    if (m_version != version)
     48        return false;
     49
     50    return (bool) (m_sections[section>>3] & BIT_SEL(section & 0x7));
     51}
     52
     53bool TableStatus::HasAllSections() const
     54{
     55    for (uint32_t i = 0; i < 32; i++)
     56        if (m_sections[i] != 0xff)
     57            return false;
     58    return true;
     59}
     60
     61
     62void TableStatusMap::SetVersion(uint32_t key, int32_t version, uint32_t last_section)
     63{
     64    TableStatus &status = (*this)[key];
     65    //NOTE: relies on status.m_version beeing invalid(-2) if a new entry was just added to the map
     66    status.SetVersion(version, last_section);
     67}
     68
     69void TableStatusMap::SetSectionSeen(uint32_t key, int32_t version, uint32_t section, uint32_t last_section)
     70{
     71    TableStatus &status = (*this)[key];
     72    //NOTE: relies on status.m_version beeing invalid(-2) if a new entry was just added to the map
     73    status.SetSectionSeen(version, section, last_section);
     74}
     75
     76bool TableStatusMap::IsSectionSeen(uint32_t key, int32_t version, uint32_t section) const
     77{
     78    const_iterator it = this->find(key);
     79    if (it == this->end() || it->m_version != version)
     80        return false;
     81    return (bool) (it->m_sections[section>>3] & BIT_SEL(section & 0x7));
     82}
     83
     84bool TableStatusMap::HasAllSections(uint32_t key) const
     85{
     86    const_iterator it = this->find(key);
     87    if (it == this->end())
     88        return false;
     89
     90    return it->HasAllSections();
     91}
     92
  • new file mythtv/libs/libmythtv/mpeg/TableStatus.h

    diff --git a/mythtv/libs/libmythtv/mpeg/TableStatus.h b/mythtv/libs/libmythtv/mpeg/TableStatus.h
    new file mode 100644
    index 0000000..9721d39
    - +  
     1// -*- Mode: c++ -*-
     2// Copyright (c) 2003-2012
     3#ifndef TABLESTATUS_H_
     4#define TABLESTATUS_H_
     5
     6// POSIX
     7#include <stdint.h>  // uint64_t
     8
     9// C++
     10#include <vector>
     11using namespace std;
     12
     13// Qt
     14#include <QMap>
     15
     16class TableStatus
     17{
     18public:
     19    typedef vector<uint8_t>   sections_t;
     20    static void InitSections(sections_t &sect, uint32_t last_section);
     21
     22    TableStatus() : m_version(-2) {}
     23    void SetVersion(int32_t version, uint32_t last_section);
     24    void SetSectionSeen(int32_t version, uint32_t section, uint32_t last_section);
     25    bool IsSectionSeen(int32_t version, uint32_t section) const;
     26    bool HasAllSections() const;
     27
     28    int32_t     m_version;
     29    sections_t  m_sections;
     30};
     31
     32class TableStatusMap : public QMap<uint32_t, TableStatus>
     33{
     34public:
     35    void SetVersion(uint32_t key, int32_t version, uint32_t last_section);
     36    void SetSectionSeen(uint32_t key, int32_t version, uint32_t section, uint32_t last_section);
     37    bool IsSectionSeen(uint32_t key, int32_t version, uint32_t section) const;
     38    bool HasAllSections(uint32_t key) const;
     39};
     40
     41#endif // TABLESTATUS_H_
     42
  • mythtv/libs/libmythtv/mpeg/atscstreamdata.cpp

    diff --git a/mythtv/libs/libmythtv/mpeg/atscstreamdata.cpp b/mythtv/libs/libmythtv/mpeg/atscstreamdata.cpp
    index 6813385..4a71a29 100644
    a b void ATSCStreamData::Reset(int major, int minor) 
    125125    _mgt_version = -1;
    126126    _tvct_version.clear();
    127127    _cvct_version.clear();
    128     _eit_version.clear();
    129     _eit_section_seen.clear();
     128    _eit_status.clear();
    130129
    131130    _sourceid_to_atsc_maj_min.clear();
    132131    _atsc_eit_pids.clear();
    bool ATSCStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    169168
    170169    if (TableID::EIT == table_id)
    171170    {
    172         if (VersionEIT(pid, psip.TableIDExtension()) != version)
    173             return false;
    174         return EITSectionSeen(pid, psip.TableIDExtension(), psip.Section());
     171        uint key = (pid<<16) | psip.TableIDExtension();
     172        return _eit_status.IsSectionSeen(key, version, psip.Section());
    175173    }
    176174
    177175    if (TableID::ETT == table_id)
    bool ATSCStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    289287            if (!_atsc_eit_listeners.size() && !_eit_helper)
    290288                return true;
    291289
    292             if (VersionEIT(pid, psip.TableIDExtension()) != version)
    293                 SetVersionEIT(pid, psip.TableIDExtension(), version);
    294             SetEITSectionSeen(pid, psip.TableIDExtension(), psip.Section());
     290            uint key = (pid<<16) | psip.TableIDExtension();
     291            _eit_status.SetSectionSeen(key, version, psip.Section(), psip.LastSection());
    295292
    296293            EventInformationTable eit(psip);
    297294            for (uint i = 0; i < _atsc_eit_listeners.size(); i++)
    bool ATSCStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    483480    return false;
    484481}
    485482
    486 void ATSCStreamData::SetEITSectionSeen(uint pid, uint atsc_source_id,
    487                                        uint section)
    488 {
    489     uint key = (pid<<16) | atsc_source_id;
    490     sections_map_t::iterator it = _eit_section_seen.find(key);
    491     if (it == _eit_section_seen.end())
    492     {
    493         _eit_section_seen[key].resize(32, 0);
    494         it = _eit_section_seen.find(key);
    495     }
    496     (*it)[section>>3] |= bit_sel[section & 0x7];
    497 }
    498 
    499 bool ATSCStreamData::EITSectionSeen(uint pid, uint atsc_source_id,
    500                                     uint section) const
    501 {
    502     uint key = (pid<<16) | atsc_source_id;
    503     sections_map_t::const_iterator it = _eit_section_seen.find(key);
    504     if (it == _eit_section_seen.end())
    505         return false;
    506     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
    507 }
    508 
    509483bool ATSCStreamData::HasEITPIDChanges(const uint_vec_t &in_use_pids) const
    510484{
    511485    QMutexLocker locker(&_listener_lock);
  • mythtv/libs/libmythtv/mpeg/atscstreamdata.h

    diff --git a/mythtv/libs/libmythtv/mpeg/atscstreamdata.h b/mythtv/libs/libmythtv/mpeg/atscstreamdata.h
    index 9feffb0..0326544 100644
    a b class MTV_PUBLIC ATSCStreamData : virtual public MPEGStreamData 
    6060        { _cvct_version[tsid] = version; }
    6161    void SetVersionRRT(uint region, int version)
    6262        { _rrt_version[region&0xff] = version; }
    63     void SetVersionEIT(uint pid, uint atsc_source_id, int version)
    64     {
    65         if (VersionEIT(pid, atsc_source_id) == version)
    66             return;
    67         uint key = (pid<<16) | atsc_source_id;
    68         _eit_version[key] = version;
    69         _eit_section_seen[key].clear();
    70         _eit_section_seen[key].resize(32, 0);
    71     }
    72     void SetEITSectionSeen(uint pid, uint atsc_source_id, uint section);
    7363
    7464    int VersionMGT() const { return _mgt_version; }
    7565    inline int VersionTVCT(uint tsid) const;
    7666    inline int VersionCVCT(uint tsid) const;
    7767    inline int VersionRRT(uint region) const;
    78     inline int VersionEIT(uint pid, uint atsc_sourceid) const;
    79     bool EITSectionSeen(uint pid, uint atsc_source_id, uint section) const;
    8068
    8169    // Caching
    8270    bool HasCachedMGT(bool current = true) const;
    class MTV_PUBLIC ATSCStreamData : virtual public MPEGStreamData 
    155143    QMap<uint, int> _tvct_version;
    156144    QMap<uint, int> _cvct_version;
    157145    QMap<uint, int> _rrt_version;
    158     QMap<uint, int> _eit_version;
    159     sections_map_t  _eit_section_seen;
     146    TableStatusMap  _eit_status;
    160147
    161148    // Caching
    162149    mutable MasterGuideTable *_cached_mgt;
    inline int ATSCStreamData::VersionRRT(uint region) const 
    205192    return *it;
    206193}
    207194
    208 inline int ATSCStreamData::VersionEIT(uint pid, uint atsc_source_id) const
    209 {
    210     uint key = (pid<<16) | atsc_source_id;
    211     const QMap<uint, int>::const_iterator it = _eit_version.find(key);
    212     if (it == _eit_version.end())
    213         return -1;
    214     return *it;
    215 }
    216 
    217195#endif
  • mythtv/libs/libmythtv/mpeg/dvbstreamdata.cpp

    diff --git a/mythtv/libs/libmythtv/mpeg/dvbstreamdata.cpp b/mythtv/libs/libmythtv/mpeg/dvbstreamdata.cpp
    index 5b1dbb6..f5eb3b2 100644
    a b using namespace std; 
    1414#define MCA_EIT_TSID 136
    1515#define MCA_EIT_PID 1018
    1616
     17
    1718// service_id is synonymous with the MPEG program number in the PMT.
    1819DVBStreamData::DVBStreamData(uint desired_netid,  uint desired_tsid,
    1920                             int desired_program, bool cacheTables)
    2021    : MPEGStreamData(desired_program, cacheTables),
    2122      _desired_netid(desired_netid), _desired_tsid(desired_tsid),
    22       _dvb_eit_dishnet_long(false),
    23       _nit_version(-2), _nito_version(-2)
     23      _dvb_eit_dishnet_long(false)
    2424{
    25     SetVersionNIT(-1,0);
    26     SetVersionNITo(-1,0);
     25    _nit_status.SetVersion(-1,0);
     26    _nito_status.SetVersion(-1,0);
    2727    AddListeningPID(DVB_NIT_PID);
    2828    AddListeningPID(DVB_SDT_PID);
    2929    AddListeningPID(DVB_TDT_PID);
    bool DVBStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    8585
    8686    if (TableID::NIT == table_id)
    8787    {
    88         if (VersionNIT() != version)
    89             return false;
    90         return NITSectionSeen(psip.Section());
     88        return _nit_status.IsSectionSeen(version, psip.Section());
    9189    }
    9290
    9391    if (TableID::SDT == table_id)
    9492    {
    95         if (VersionSDT(psip.TableIDExtension()) != version)
    96             return false;
    97         return SDTSectionSeen(psip.TableIDExtension(), psip.Section());
     93        return _sdt_status.IsSectionSeen(psip.TableIDExtension(), version, psip.Section());
    9894    }
    9995
    10096    if (TableID::TDT == table_id)
    bool DVBStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    10298
    10399    if (TableID::BAT == table_id)
    104100    {
    105         if (VersionBAT(psip.TableIDExtension()) != version)
    106             return false;
    107         return BATSectionSeen(psip.TableIDExtension(), psip.Section());
     101        return _bat_status.IsSectionSeen(psip.TableIDExtension(), version, psip.Section());
    108102    }
    109103
    110104    bool is_eit = false;
    bool DVBStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    119113    if (is_eit)
    120114    {
    121115        uint service_id = psip.TableIDExtension();
    122         if (VersionEIT(table_id, service_id) != version)
    123             return false;
    124         return EITSectionSeen(table_id, service_id, psip.Section());
     116        uint key = (table_id<<16) | service_id;
     117        return _eit_status.IsSectionSeen(key, version, psip.Section());
    125118    }
    126119
    127120    ////////////////////////////////////////////////////////////////////////
    bool DVBStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    129122
    130123    if (TableID::NITo == table_id)
    131124    {
    132         if (VersionNITo() != version)
    133             return false;
    134         return NIToSectionSeen(psip.Section());
     125        return _nito_status.IsSectionSeen(version, psip.Section());
    135126    }
    136127
    137128    if (TableID::SDTo == table_id)
    138129    {
    139         if (VersionSDTo(psip.TableIDExtension()) != version)
    140             return false;
    141         return SDToSectionSeen(psip.TableIDExtension(), psip.Section());
     130        return _sdto_status.IsSectionSeen(psip.TableIDExtension(), version, psip.Section());
    142131    }
    143132
    144133    if (DVB_EIT_PID == pid || FREESAT_EIT_PID == pid || MCA_EIT_PID == pid)
    bool DVBStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    159148    if (is_eit)
    160149    {
    161150        uint service_id = psip.TableIDExtension();
    162         if (VersionEIT(table_id, service_id) != version)
    163             return false;
    164         return EITSectionSeen(table_id, service_id, psip.Section());
     151        uint key = (table_id<<16) | service_id;
     152        return _eit_status.IsSectionSeen(key, version, psip.Section());
    165153    }
    166154
    167155    if (((PREMIERE_EIT_DIREKT_PID == pid) || (PREMIERE_EIT_SPORT_PID == pid)) &&
    168156        TableID::PREMIERE_CIT == table_id)
    169157    {
    170158        uint content_id = PremiereContentInformationTable(psip).ContentID();
    171         if (VersionCIT(content_id) != version)
    172             return false;
    173         return CITSectionSeen(content_id, psip.Section());
     159        return _cit_status.IsSectionSeen(content_id, version, psip.Section());
    174160    }
    175161
    176162    return false;
    void DVBStreamData::Reset(uint desired_netid, uint desired_tsid, 
    184170    _desired_netid = desired_netid;
    185171    _desired_tsid  = desired_tsid;
    186172
    187     SetVersionNIT(-1,0);
    188     _sdt_versions.clear();
    189     _sdt_section_seen.clear();
    190     _eit_version.clear();
    191     _eit_section_seen.clear();
    192     _cit_version.clear();
    193     _cit_section_seen.clear();
     173    _nit_status.SetVersion(-1,0);
     174    _sdt_status.clear();
     175    _eit_status.clear();
     176    _cit_status.clear();
    194177
    195     SetVersionNITo(-1,0);
    196     _sdto_versions.clear();
    197     _sdto_section_seen.clear();
    198     _bat_versions.clear();
    199     _bat_section_seen.clear();
     178    _nito_status.SetVersion(-1,0);
     179    _sdto_status.clear();
     180    _bat_status.clear();
    200181
    201182    {
    202183        _cache_lock.lock();
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    234215    {
    235216        case TableID::NIT:
    236217        {
    237             SetVersionNIT(psip.Version(), psip.LastSection());
    238             SetNITSectionSeen(psip.Section());
     218            _nit_status.SetSectionSeen(psip.Version(), psip.Section(), psip.LastSection());
    239219
    240220            if (_cache_tables)
    241221            {
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    259239        case TableID::SDT:
    260240        {
    261241            uint tsid = psip.TableIDExtension();
    262             SetVersionSDT(tsid, psip.Version(), psip.LastSection());
    263             SetSDTSectionSeen(tsid, psip.Section());
     242            _sdt_status.SetSectionSeen(tsid, psip.Version(), psip.Section(), psip.LastSection());
    264243
    265244            if (_cache_tables)
    266245            {
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    291270        }
    292271        case TableID::NITo:
    293272        {
    294             SetVersionNITo(psip.Version(), psip.LastSection());
    295             SetNIToSectionSeen(psip.Section());
     273            _nito_status.SetSectionSeen(psip.Version(), psip.Section(), psip.LastSection());
    296274            NetworkInformationTable nit(psip);
    297275
    298276            QMutexLocker locker(&_listener_lock);
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    304282        case TableID::SDTo:
    305283        {
    306284            uint tsid = psip.TableIDExtension();
    307             SetVersionSDTo(tsid, psip.Version(), psip.LastSection());
    308             SetSDToSectionSeen(tsid, psip.Section());
     285            _sdto_status.SetSectionSeen(tsid, psip.Version(), psip.Section(), psip.LastSection());
    309286            ServiceDescriptionTable sdt(psip);
    310287
    311288            // some providers send the SDT for the current multiplex as SDTo
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    342319        case TableID::BAT:
    343320        {
    344321            uint bid = psip.TableIDExtension();
    345             SetVersionBAT(bid, psip.Version(), psip.LastSection());
    346             SetBATSectionSeen(bid, psip.Section());
     322            _bat_status.SetSectionSeen(bid, psip.Version(), psip.Section(), psip.LastSection());
    347323            BouquetAssociationTable bat(psip);
    348324
    349325            QMutexLocker locker(&_listener_lock);
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    365341            return true;
    366342
    367343        uint service_id = psip.TableIDExtension();
    368         SetVersionEIT(psip.TableID(), service_id, psip.Version(),  psip.LastSection());
    369         SetEITSectionSeen(psip.TableID(), service_id, psip.Section());
     344        uint key = (psip.TableID()<<16) | service_id;
     345        _eit_status.SetSectionSeen(key, psip.Version(), psip.Section(), psip.LastSection());
    370346
    371347        DVBEventInformationTable eit(psip);
    372348        for (uint i = 0; i < _dvb_eit_listeners.size(); i++)
    bool DVBStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    387363            return true;
    388364
    389365        PremiereContentInformationTable cit(psip);
    390         SetVersionCIT(cit.ContentID(), cit.Version());
    391         SetCITSectionSeen(cit.ContentID(), cit.Section());
     366        _cit_status.SetSectionSeen(cit.ContentID(), psip.Version(), psip.Section(), psip.LastSection());
    392367
    393368        for (uint i = 0; i < _dvb_eit_listeners.size(); i++)
    394369            _dvb_eit_listeners[i]->HandleEIT(&cit);
    bool DVBStreamData::GetEITPIDChanges(const uint_vec_t &cur_pids, 
    533508    return add_pids.size() || del_pids.size();
    534509}
    535510
    536 void DVBStreamData::SetNITSectionSeen(uint section)
    537 {
    538     _nit_section_seen[section>>3] |= bit_sel[section & 0x7];
    539 }
    540 
    541 bool DVBStreamData::NITSectionSeen(uint section) const
    542 {
    543     return (bool) (_nit_section_seen[section>>3] & bit_sel[section & 0x7]);
    544 }
    545 
    546511bool DVBStreamData::HasAllNITSections(void) const
    547512{
    548     for (uint i = 0; i < 32; i++)
    549         if (_nit_section_seen[i] != 0xff)
    550             return false;
    551     return true;
    552 }
    553 
    554 void DVBStreamData::SetNIToSectionSeen(uint section)
    555 {
    556     _nito_section_seen[section>>3] |= bit_sel[section & 0x7];
    557 }
    558 
    559 bool DVBStreamData::NIToSectionSeen(uint section) const
    560 {
    561     return (bool) (_nito_section_seen[section>>3] & bit_sel[section & 0x7]);
     513    return _nit_status.HasAllSections();
    562514}
    563515
    564516bool DVBStreamData::HasAllNIToSections(void) const
    565517{
    566     for (uint i = 0; i < 32; i++)
    567         if (_nito_section_seen[i] != 0xff)
    568             return false;
    569     return true;
    570 }
    571 
    572 void DVBStreamData::SetSDTSectionSeen(uint tsid, uint section)
    573 {
    574     sections_map_t::iterator it = _sdt_section_seen.find(tsid);
    575     if (it == _sdt_section_seen.end())
    576     {
    577         _sdt_section_seen[tsid].resize(32, 0);
    578         it = _sdt_section_seen.find(tsid);
    579     }
    580     (*it)[section>>3] |= bit_sel[section & 0x7];
    581 }
    582 
    583 bool DVBStreamData::SDTSectionSeen(uint tsid, uint section) const
    584 {
    585     sections_map_t::const_iterator it = _sdt_section_seen.find(tsid);
    586     if (it == _sdt_section_seen.end())
    587         return false;
    588     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
     518    return _nito_status.HasAllSections();
    589519}
    590520
    591521bool DVBStreamData::HasAllSDTSections(uint tsid) const
    592522{
    593     sections_map_t::const_iterator it = _sdt_section_seen.find(tsid);
    594     if (it == _sdt_section_seen.end())
    595         return false;
    596     for (uint i = 0; i < 32; i++)
    597         if ((*it)[i] != 0xff)
    598             return false;
    599     return true;
    600 }
    601 
    602 void DVBStreamData::SetSDToSectionSeen(uint tsid, uint section)
    603 {
    604     sections_map_t::iterator it = _sdto_section_seen.find(tsid);
    605     if (it == _sdto_section_seen.end())
    606     {
    607         _sdto_section_seen[tsid].resize(32, 0);
    608         it = _sdto_section_seen.find(tsid);
    609     }
    610     (*it)[section>>3] |= bit_sel[section & 0x7];
    611 }
    612 
    613 bool DVBStreamData::SDToSectionSeen(uint tsid, uint section) const
    614 {
    615     sections_map_t::const_iterator it = _sdto_section_seen.find(tsid);
    616     if (it == _sdto_section_seen.end())
    617         return false;
    618     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
     523    return _sdt_status.HasAllSections(tsid);
    619524}
    620525
    621526bool DVBStreamData::HasAllSDToSections(uint tsid) const
    622527{
    623     sections_map_t::const_iterator it = _sdto_section_seen.find(tsid);
    624     if (it == _sdto_section_seen.end())
    625         return false;
    626     for (uint i = 0; i < 32; i++)
    627         if ((*it)[i] != 0xff)
    628             return false;
    629     return true;
    630 }
    631 
    632 void DVBStreamData::SetBATSectionSeen(uint bid, uint section)
    633 {
    634     sections_map_t::iterator it = _bat_section_seen.find(bid);
    635     if (it == _bat_section_seen.end())
    636     {
    637         _bat_section_seen[bid].resize(32, 0);
    638         it = _bat_section_seen.find(bid);
    639     }
    640     (*it)[section>>3] |= bit_sel[section & 0x7];
    641 }
    642 
    643 bool DVBStreamData::BATSectionSeen(uint bid, uint section) const
    644 {
    645     sections_map_t::const_iterator it = _bat_section_seen.find(bid);
    646     if (it == _bat_section_seen.end())
    647         return false;
    648     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
     528    return _sdto_status.HasAllSections(tsid);
    649529}
    650530
    651531bool DVBStreamData::HasAllBATSections(uint bid) const
    652532{
    653     sections_map_t::const_iterator it = _bat_section_seen.find(bid);
    654     if (it == _bat_section_seen.end())
    655         return false;
    656     for (uint i = 0; i < 32; i++)
    657         if ((*it)[i] != 0xff)
    658             return false;
    659     return true;
    660 }
    661 
    662 void DVBStreamData::SetEITSectionSeen(uint tableid, uint serviceid,
    663                                       uint section)
    664 {
    665     uint key = (tableid<<16) | serviceid;
    666     sections_map_t::iterator it = _eit_section_seen.find(key);
    667     if (it == _eit_section_seen.end())
    668     {
    669         _eit_section_seen[key].resize(32, 0);
    670         it = _eit_section_seen.find(key);
    671     }
    672     (*it)[section>>3] |= bit_sel[section & 0x7];
    673 }
    674 
    675 bool DVBStreamData::EITSectionSeen(uint tableid, uint serviceid,
    676                                    uint section) const
    677 {
    678     uint key = (tableid<<16) | serviceid;
    679     sections_map_t::const_iterator it = _eit_section_seen.find(key);
    680     if (it == _eit_section_seen.end())
    681         return false;
    682     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
    683 }
    684 
    685 void DVBStreamData::SetCITSectionSeen(uint contentid, uint section)
    686 {
    687     sections_map_t::iterator it = _cit_section_seen.find(contentid);
    688     if (it == _cit_section_seen.end())
    689     {
    690         _cit_section_seen[contentid].resize(32, 0);
    691         it = _cit_section_seen.find(contentid);
    692     }
    693     (*it)[section>>3] |= bit_sel[section & 0x7];
    694 }
    695 
    696 bool DVBStreamData::CITSectionSeen(uint contentid, uint section) const
    697 {
    698     sections_map_t::const_iterator it = _cit_section_seen.find(contentid);
    699     if (it == _cit_section_seen.end())
    700         return false;
    701     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
     533    return _bat_status.HasAllSections(bid);
    702534}
    703535
    704536bool DVBStreamData::HasCachedAnyNIT(bool current) const
  • mythtv/libs/libmythtv/mpeg/dvbstreamdata.h

    diff --git a/mythtv/libs/libmythtv/mpeg/dvbstreamdata.h b/mythtv/libs/libmythtv/mpeg/dvbstreamdata.h
    index ed5583a..a74bef3 100644
    a b  
    55
    66#include "mpegstreamdata.h"
    77#include "mythtvexp.h"
     8#include "TableStatus.h"
    89
    910typedef NetworkInformationTable* nit_ptr_t;
    1011typedef NetworkInformationTable const* nit_const_ptr_t;
    class MTV_PUBLIC DVBStreamData : virtual public MPEGStreamData 
    5354                          uint_vec_t &del_pids) const;
    5455
    5556    // Table versions
    56     void SetVersionNIT(int version, uint last_section)
    57     {
    58         if (_nit_version == version)
    59             return;
    60         _nit_version = version;
    61         init_sections(_nit_section_seen, last_section);
    62     }
    63     int  VersionNIT() const { return _nit_version; }
    64 
    65     void SetVersionNITo(int version, uint last_section)
    66     {
    67         if (_nito_version == version)
    68             return;
    69         _nito_version = version;
    70         init_sections(_nito_section_seen, last_section);
    71     }
    72     int  VersionNITo() const { return _nito_version; }
    73 
    7457    void SetVersionSDT(uint tsid, int version, uint last_section)
    7558    {
    76         if (VersionSDT(tsid) == version)
    77             return;
    78         _sdt_versions[tsid] = version;
    79         init_sections(_sdt_section_seen[tsid], last_section);
     59        _sdt_status.SetVersion(tsid, version, last_section);
    8060    }
    81     int VersionSDT(uint tsid) const
    82     {
    83         const QMap<uint, int>::const_iterator it = _sdt_versions.find(tsid);
    84         if (it == _sdt_versions.end())
    85             return -1;
    86         return *it;
    87     }
    88 
    89     void SetVersionSDTo(uint tsid, int version, uint last_section)
    90     {
    91         if (_sdto_versions[tsid] == version)
    92             return;
    93         _sdto_versions[tsid] = version;
    94         init_sections(_sdto_section_seen[tsid], last_section);
    95     }
    96     int VersionSDTo(uint tsid) const
    97     {
    98         const QMap<uint, int>::const_iterator it = _sdto_versions.find(tsid);
    99         if (it == _sdto_versions.end())
    100             return -1;
    101         return *it;
    102     }
    103 
    104     void SetVersionEIT(uint tableid, uint serviceid, int version, uint last_section)
    105     {
    106         if (VersionEIT(tableid, serviceid) == version)
    107             return;
    108         uint key = (tableid << 16) | serviceid;
    109         _eit_version[key] = version;
    110         init_sections(_eit_section_seen[key], last_section);
    111     }
    112 
    113     int VersionEIT(uint tableid, uint serviceid) const
    114     {
    115         uint key = (tableid << 16) | serviceid;
    116         const QMap<uint, int>::const_iterator it = _eit_version.find(key);
    117         if (it == _eit_version.end())
    118             return -1;
    119         return *it;
    120     }
    121 
    122     void SetVersionBAT(uint bid, int version, uint last_section)
    123     {
    124         if (_bat_versions[bid] == version)
    125             return;
    126         _bat_versions[bid] = version;
    127         init_sections(_bat_section_seen[bid], last_section);
    128     }
    129     int VersionBAT(uint bid) const
    130     {
    131         const QMap<uint, int>::const_iterator it = _bat_versions.find(bid);
    132         if (it == _bat_versions.end())
    133             return -1;
    134         return *it;
    135     }
    136 
    137     // Premiere private ContentInformationTable
    138     void SetVersionCIT(uint contentid, int version)
    139     {
    140         if (VersionCIT(contentid) == version)
    141             return;
    142         _cit_version[contentid] = version;
    143     }
    144 
    145     int VersionCIT(uint contentid) const
    146     {
    147         const QMap<uint, int>::const_iterator it = _cit_version.find(contentid);
    148         if (it == _cit_version.end())
    149             return -1;
    150         return *it;
    151     }
    152 
    15361    // Sections seen
    154     void SetNITSectionSeen(uint section);
    155     bool NITSectionSeen(uint section) const;
    15662    bool HasAllNITSections(void) const;
    15763
    158     void SetNIToSectionSeen(uint section);
    159     bool NIToSectionSeen(uint section) const;
    16064    bool HasAllNIToSections(void) const;
    16165
    162     void SetSDTSectionSeen(uint tsid, uint section);
    163     bool SDTSectionSeen(uint tsid, uint section) const;
    16466    bool HasAllSDTSections(uint tsid) const;
    16567
    166     void SetSDToSectionSeen(uint tsid, uint section);
    167     bool SDToSectionSeen(uint tsid, uint section) const;
    16868    bool HasAllSDToSections(uint tsid) const;
    16969
    170     void SetEITSectionSeen(uint tableid, uint serviceid, uint section);
    171     bool EITSectionSeen(uint tableid, uint serviceid, uint section) const;
    172 
    173     void SetBATSectionSeen(uint bid, uint section);
    174     bool BATSectionSeen(uint bid, uint section) const;
    17570    bool HasAllBATSections(uint bid) const;
    17671
    177     // Premiere private ContentInformationTable
    178     void SetCITSectionSeen(uint contentid, uint section);
    179     bool CITSectionSeen(uint contentid, uint section) const;
    180 
    18172    // Caching
    18273    bool HasCachedAnyNIT(bool current = true) const;
    18374    bool HasCachedAllNIT(bool current = true) const;
    class MTV_PUBLIC DVBStreamData : virtual public MPEGStreamData 
    226117    dvb_eit_listener_vec_t    _dvb_eit_listeners;
    227118
    228119    // Table versions
    229     int                       _nit_version;
    230     QMap<uint, int>           _sdt_versions;
    231     sections_t                _nit_section_seen;
    232     sections_map_t            _sdt_section_seen;
    233     QMap<uint, int>           _eit_version;
    234     sections_map_t            _eit_section_seen;
     120    TableStatus               _nit_status;
     121    TableStatusMap            _sdt_status;
     122    TableStatusMap            _eit_status;
    235123    // Premiere private ContentInformationTable
    236     QMap<uint, int>           _cit_version;
    237     sections_map_t            _cit_section_seen;
    238 
    239     int                       _nito_version;
    240     QMap<uint, int>           _sdto_versions;
    241     sections_t                _nito_section_seen;
    242     sections_map_t            _sdto_section_seen;
    243     QMap<uint, int>           _bat_versions;
    244     sections_map_t            _bat_section_seen;
     124    TableStatusMap            _cit_status;
     125
     126    TableStatus               _nito_status;
     127    TableStatusMap            _sdto_status;
     128    TableStatusMap            _bat_status;
    245129
    246130    // Caching
    247131    mutable nit_cache_t       _cached_nit;  // section -> sdt
  • mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp

    diff --git a/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp b/mythtv/libs/libmythtv/mpeg/mpegstreamdata.cpp
    index 8a2946d..1e52599 100644
    a b using namespace std; 
    2121
    2222//#define DEBUG_MPEG_RADIO // uncomment to strip video streams from TS stream
    2323
    24 void init_sections(sections_t &sect, uint last_section)
    25 {
    26     static const unsigned char init_bits[8] =
    27         { 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, };
    28 
    29     sect.clear();
    30 
    31     uint endz = last_section >> 3;
    32     if (endz)
    33         sect.resize(endz, 0x00);
    34     sect.resize(32, 0xff);
    35     sect[endz] = init_bits[last_section & 0x7];
    36 
    37 #if 0
    38     {
    39         QString msg = QString("init_sections ls(%1): ").arg(last_section);
    40         for (uint i = 0 ; i < 32; i++)
    41             msg += QString("%1 ").arg((int)sect[i], 0, 16);
    42         LOG(VB_GENERAL, LOG_DEBUG, msg);
    43     }
    44 #endif
    45 }
    46 
    47 const unsigned char MPEGStreamData::bit_sel[8] =
    48 {
    49     0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80,
    50 };
    51 
    5224/** \class MPEGStreamData
    5325 *  \brief Encapsulates data about MPEG stream and emits events for each table.
    5426 */
    void MPEGStreamData::Reset(int desiredProgram) 
    192164
    193165    _pid_video_single_program = _pid_pmt_single_program = 0xffffffff;
    194166
    195     _pat_version.clear();
    196     _pat_section_seen.clear();
     167    _pat_status.clear();
    197168
    198     _pmt_version.clear();
    199     _pmt_section_seen.clear();
     169    _pmt_status.clear();
    200170
    201171    {
    202172        QMutexLocker locker(&_cache_lock);
    bool MPEGStreamData::IsRedundant(uint pid, const PSIPTable &psip) const 
    692662
    693663    if (TableID::PAT == table_id)
    694664    {
    695         if (VersionPAT(psip.TableIDExtension()) != version)
    696             return false;
    697         return PATSectionSeen(psip.TableIDExtension(), psip.Section());
     665        return _pat_status.IsSectionSeen(psip.TableIDExtension(), version, psip.Section());
    698666    }
    699667
    700668    if (TableID::CAT == table_id)
    701669    {
    702         if (VersionCAT(psip.TableIDExtension()) != version)
    703            return false;
    704         return CATSectionSeen(psip.TableIDExtension(), psip.Section());
     670        return _cat_status.IsSectionSeen(psip.TableIDExtension(), version, psip.Section());
    705671    }
    706672
    707673    if (TableID::PMT == table_id)
    708674    {
    709         if (VersionPMT(psip.TableIDExtension()) != version)
    710             return false;
    711         return PMTSectionSeen(psip.TableIDExtension(), psip.Section());
     675        return _pmt_status.IsSectionSeen(psip.TableIDExtension(), version, psip.Section());
    712676    }
    713677
    714678    return false;
    bool MPEGStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    729693        case TableID::PAT:
    730694        {
    731695            uint tsid = psip.TableIDExtension();
    732             SetVersionPAT(tsid, version, psip.LastSection());
    733             SetPATSectionSeen(tsid, psip.Section());
     696            _pat_status.SetSectionSeen(tsid, version, psip.Section(), psip.LastSection());
    734697
    735698            ProgramAssociationTable pat(psip);
    736699
    bool MPEGStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    744707        case TableID::CAT:
    745708        {
    746709            uint tsid = psip.TableIDExtension();
    747             SetVersionCAT(tsid, version, psip.LastSection());
    748             SetCATSectionSeen(tsid, psip.Section());
     710            _cat_status.SetSectionSeen(tsid, version, psip.Section(), psip.LastSection());
    749711
    750712            ConditionalAccessTable cat(psip);
    751713
    bool MPEGStreamData::HandleTables(uint pid, const PSIPTable &psip) 
    759721        case TableID::PMT:
    760722        {
    761723            uint prog_num = psip.TableIDExtension();
    762             SetVersionPMT(prog_num, version, psip.LastSection());
    763             SetPMTSectionSeen(prog_num, psip.Section());
     724            _pmt_status.SetSectionSeen(prog_num, version, psip.Section(), psip.LastSection());
    764725
    765726            ProgramMapTable pmt(psip);
    766727
    void MPEGStreamData::SavePartialPSIP(uint pid, PSIPTable* packet) 
    11881149    }
    11891150}
    11901151
    1191 void MPEGStreamData::SetPATSectionSeen(uint tsid, uint section)
    1192 {
    1193     sections_map_t::iterator it = _pat_section_seen.find(tsid);
    1194     if (it == _pat_section_seen.end())
    1195     {
    1196         _pat_section_seen[tsid].resize(32, 0);
    1197         it = _pat_section_seen.find(tsid);
    1198     }
    1199     (*it)[section>>3] |= bit_sel[section & 0x7];
    1200 }
    1201 
    1202 bool MPEGStreamData::PATSectionSeen(uint tsid, uint section) const
    1203 {
    1204     sections_map_t::const_iterator it = _pat_section_seen.find(tsid);
    1205     if (it == _pat_section_seen.end())
    1206         return false;
    1207     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
    1208 }
    1209 
    12101152bool MPEGStreamData::HasAllPATSections(uint tsid) const
    12111153{
    1212     sections_map_t::const_iterator it = _pat_section_seen.find(tsid);
    1213     if (it == _pat_section_seen.end())
    1214         return false;
    1215     for (uint i = 0; i < 32; i++)
    1216         if ((*it)[i] != 0xff)
    1217             return false;
    1218     return true;
    1219 }
    1220 
    1221 void MPEGStreamData::SetCATSectionSeen(uint tsid, uint section)
    1222 {
    1223     sections_map_t::iterator it = _cat_section_seen.find(tsid);
    1224     if (it == _cat_section_seen.end())
    1225     {
    1226         _cat_section_seen[tsid].resize(32, 0);
    1227         it = _cat_section_seen.find(tsid);
    1228     }
    1229     (*it)[section>>3] |= bit_sel[section & 0x7];
    1230 }
    1231 
    1232 bool MPEGStreamData::CATSectionSeen(uint tsid, uint section) const
    1233 {
    1234     sections_map_t::const_iterator it = _cat_section_seen.find(tsid);
    1235     if (it == _cat_section_seen.end())
    1236         return false;
    1237     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
     1154    return _pat_status.HasAllSections(tsid);
    12381155}
    12391156
    12401157bool MPEGStreamData::HasAllCATSections(uint tsid) const
    12411158{
    1242     sections_map_t::const_iterator it = _cat_section_seen.find(tsid);
    1243     if (it == _cat_section_seen.end())
    1244         return false;
    1245     for (uint i = 0; i < 32; i++)
    1246         if ((*it)[i] != 0xff)
    1247             return false;
    1248     return true;
    1249 }
    1250 
    1251 void MPEGStreamData::SetPMTSectionSeen(uint prog_num, uint section)
    1252 {
    1253     sections_map_t::iterator it = _pmt_section_seen.find(prog_num);
    1254     if (it == _pmt_section_seen.end())
    1255     {
    1256         _pmt_section_seen[prog_num].resize(32, 0);
    1257         it = _pmt_section_seen.find(prog_num);
    1258     }
    1259     (*it)[section>>3] |= bit_sel[section & 0x7];
    1260 }
    1261 
    1262 bool MPEGStreamData::PMTSectionSeen(uint prog_num, uint section) const
    1263 {
    1264     sections_map_t::const_iterator it = _pmt_section_seen.find(prog_num);
    1265     if (it == _pmt_section_seen.end())
    1266         return false;
    1267     return (bool) ((*it)[section>>3] & bit_sel[section & 0x7]);
     1159    return _cat_status.HasAllSections(tsid);
    12681160}
    12691161
    12701162bool MPEGStreamData::HasAllPMTSections(uint prog_num) const
    12711163{
    1272     sections_map_t::const_iterator it = _pmt_section_seen.find(prog_num);
    1273     if (it == _pmt_section_seen.end())
    1274         return false;
    1275     for (uint i = 0; i < 32; i++)
    1276         if ((*it)[i] != 0xff)
    1277             return false;
    1278     return true;
     1164    return _pmt_status.HasAllSections(prog_num);
    12791165}
    12801166
    12811167bool MPEGStreamData::HasProgram(uint progNum) const
  • mythtv/libs/libmythtv/mpeg/mpegstreamdata.h

    diff --git a/mythtv/libs/libmythtv/mpeg/mpegstreamdata.h b/mythtv/libs/libmythtv/mpeg/mpegstreamdata.h
    index e56e9bc..4eb83d2 100644
    a b using namespace std; 
    1818#include "streamlisteners.h"
    1919#include "eitscanner.h"
    2020#include "mythtvexp.h"
     21#include "TableStatus.h"
    2122
    2223class EITHelper;
    2324class PSIPTable;
    typedef QMap<uint, pmt_vec_t> pmt_map_t; 
    4748typedef QMap<uint, ProgramMapTable*>    pmt_cache_t;
    4849
    4950typedef vector<unsigned char>           uchar_vec_t;
    50 typedef uchar_vec_t                     sections_t;
    51 typedef QMap<uint, sections_t>          sections_map_t;
    5251
    5352typedef vector<MPEGStreamListener*>     mpeg_listener_vec_t;
    5453typedef vector<TSPacketListener*>       ts_listener_vec_t;
    class MTV_PUBLIC CryptInfo 
    8079    uint decrypted_min;
    8180};
    8281
    83 void init_sections(sections_t &sect, uint last_section);
    84 
    8582typedef enum
    8683{
    8784    kPIDPriorityNone   = 0,
    class MTV_PUBLIC MPEGStreamData : public EITSource 
    166163    // Table versions
    167164    void SetVersionPAT(uint tsid, int version, uint last_section)
    168165    {
    169         if (VersionPAT(tsid) == version)
    170             return;
    171         _pat_version[tsid] = version;
    172         init_sections(_pat_section_seen[tsid], last_section);
    173     }
    174     int  VersionPAT(uint tsid) const
    175     {
    176         const QMap<uint, int>::const_iterator it = _pat_version.find(tsid);
    177         if (it == _pat_version.end())
    178             return -1;
    179         return *it;
    180     }
    181 
    182     void SetVersionCAT(uint tsid, int version, uint last_section)
    183     {
    184         if (VersionCAT(tsid) == version)
    185             return;
    186         _cat_version[tsid] = version;
    187         init_sections(_cat_section_seen[tsid], last_section);
    188     }
    189     int  VersionCAT(uint tsid) const
    190     {
    191         const QMap<uint, int>::const_iterator it = _cat_version.find(tsid);
    192         if (it == _cat_version.end())
    193             return -1;
    194         return *it;
    195     }
    196 
    197     void SetVersionPMT(uint program_num, int version, uint last_section)
    198     {
    199         if (VersionPMT(program_num) == version)
    200             return;
    201         _pmt_version[program_num] = version;
    202         init_sections(_pmt_section_seen[program_num], last_section);
    203     }
    204     int  VersionPMT(uint prog_num) const
    205     {
    206         const QMap<uint, int>::const_iterator it = _pmt_version.find(prog_num);
    207         if (it == _pmt_version.end())
    208             return -1;
    209         return *it;
     166        _pat_status.SetVersion(tsid, version, last_section);
    210167    }
    211168
    212169    // Sections seen
    213     void SetPATSectionSeen(uint tsid, uint section);
    214     bool PATSectionSeen(   uint tsid, uint section) const;
    215170    bool HasAllPATSections(uint tsid) const;
    216171
    217     void SetCATSectionSeen(uint tsid, uint section);
    218     bool CATSectionSeen(   uint tsid, uint section) const;
    219172    bool HasAllCATSections(uint tsid) const;
    220173
    221     void SetPMTSectionSeen(uint prog_num, uint section);
    222     bool PMTSectionSeen(   uint prog_num, uint section) const;
    223174    bool HasAllPMTSections(uint prog_num) const;
    224175
    225176    // Caching
    class MTV_PUBLIC MPEGStreamData : public EITSource 
    388339    ts_av_listener_vec_t      _ts_av_listeners;
    389340
    390341    // Table versions
    391     QMap<uint, int>           _pat_version;
    392     QMap<uint, int>           _cat_version;
    393     QMap<uint, int>           _pmt_version;
    394 
    395     sections_map_t            _pat_section_seen;
    396     sections_map_t            _cat_section_seen;
    397     sections_map_t            _pmt_section_seen;
     342    TableStatusMap            _pat_status;
     343    TableStatusMap            _cat_status;
     344    TableStatusMap            _pmt_status;
    398345
    399346    // PSIP construction
    400347    pid_psip_map_t            _partial_psip_packet_cache;
    class MTV_PUBLIC MPEGStreamData : public EITSource 
    425372    bool                      _invalid_pat_seen;
    426373    bool                      _invalid_pat_warning;
    427374    MythTimer                 _invalid_pat_timer;
    428 
    429   protected:
    430     static const unsigned char bit_sel[8];
    431375};
    432376
    433377#include "mpegtables.h"