Ticket #12932: dvbstreamdata.h

File dvbstreamdata.h, 11.0 KB (added by Roger James <roger@…>, 7 years ago)
Line 
1// -*- Mode: c++ -*-
2// Copyright (c) 2003-2004, Daniel Thor Kristjansson
3#ifndef DVBSTREAMDATA_H_
4#define DVBSTREAMDATA_H_
5
6#include "mpegstreamdata.h"
7#include "mythtvexp.h"
8
9typedef NetworkInformationTable* nit_ptr_t;
10typedef NetworkInformationTable const* nit_const_ptr_t;
11typedef vector<const NetworkInformationTable*>  nit_vec_t;
12typedef QMap<uint, nit_ptr_t>    nit_cache_t; // section->sdts
13
14typedef ServiceDescriptionTable* sdt_ptr_t;
15typedef ServiceDescriptionTable const* sdt_const_ptr_t;
16typedef vector<const ServiceDescriptionTable*>  sdt_vec_t;
17typedef QMap<uint, sdt_ptr_t>    sdt_cache_t; // tsid+section->sdts
18typedef QMap<uint, sdt_vec_t>    sdt_map_t;   // tsid->sdts
19
20typedef vector<DVBMainStreamListener*>   dvb_main_listener_vec_t;
21typedef vector<DVBOtherStreamListener*>  dvb_other_listener_vec_t;
22typedef vector<DVBEITStreamListener*>    dvb_eit_listener_vec_t;
23
24typedef QMap<uint, bool>                 dvb_has_eit_t;
25
26class MTV_PUBLIC DVBStreamData : virtual public MPEGStreamData
27{
28  public:
29    DVBStreamData(uint desired_netid, uint desired_tsid,
30                  int desired_program, int cardnum, bool cacheTables = false);
31    virtual ~DVBStreamData();
32
33    using MPEGStreamData::Reset;
34    void Reset(void) { Reset(0, 0, -1); }
35    void Reset(uint desired_netid, uint desired_tsid, int desired_sid);
36
37    // DVB table monitoring
38    void SetDesiredService(uint netid, uint tsid, int serviceid);
39    uint DesiredNetworkID(void)   const { return _desired_netid; }
40    uint DesiredTransportID(void) const { return _desired_tsid;  }
41
42    // Table processing
43    bool HandleTables(uint pid, const PSIPTable&);
44    bool IsRedundant(uint pid, const PSIPTable&) const;
45    void ProcessSDT(uint tsid, const ServiceDescriptionTable*);
46
47    // NIT for broken providers
48    inline void SetRealNetworkID(int);
49
50    // EIT info/processing
51    inline void SetDishNetEIT(bool);
52    inline bool HasAnyEIT(void) const;
53    inline bool HasEIT(uint serviceid) const;
54    bool HasEITPIDChanges(const uint_vec_t &in_use_pids) const;
55    bool GetEITPIDChanges(const uint_vec_t &in_use_pids,
56                          uint_vec_t &add_pids,
57                          uint_vec_t &del_pids) const;
58
59    // Table versions
60    void SetVersionNIT(int version, uint last_section)
61    {
62        if (_nit_version == version)
63            return;
64        _nit_version = version;
65        init_sections(_nit_section_seen, last_section);
66    }
67    int  VersionNIT() const { return _nit_version; }
68
69    void SetVersionNITo(int version, uint last_section)
70    {
71        if (_nito_version == version)
72            return;
73        _nito_version = version;
74        init_sections(_nito_section_seen, last_section);
75    }
76    int  VersionNITo() const { return _nito_version; }
77
78    void SetVersionSDT(uint tsid, int version, uint last_section)
79    {
80        if (VersionSDT(tsid) == version)
81            return;
82        _sdt_versions[tsid] = version;
83        init_sections(_sdt_section_seen[tsid], last_section);
84    }
85    int VersionSDT(uint tsid) const
86    {
87        const QMap<uint, int>::const_iterator it = _sdt_versions.find(tsid);
88        if (it == _sdt_versions.end())
89            return -1;
90        return *it;
91    }
92
93    void SetVersionSDTo(uint tsid, int version, uint last_section)
94    {
95        if (_sdto_versions[tsid] == version)
96            return;
97        _sdto_versions[tsid] = version;
98        init_sections(_sdto_section_seen[tsid], last_section);
99    }
100    int VersionSDTo(uint tsid) const
101    {
102        const QMap<uint, int>::const_iterator it = _sdto_versions.find(tsid);
103        if (it == _sdto_versions.end())
104            return -1;
105        return *it;
106    }
107
108    static uint GenerateUniqueUKOriginalNetworkID(uint transport_stream_id)
109    {
110        // Convert United Kingdom DTT id to temporary temporary local range
111        uint mux_id = (transport_stream_id & 0x3f000) >> 12;
112        if (mux_id > 0xb)
113            mux_id = 0;
114        if ((mux_id == 0x7) && ((transport_stream_id & 0xfff) < 0x3ff))
115            mux_id = 0xc;
116        // Shift id to private temporary use range
117        return 0xff01  + mux_id;
118    }
119
120    void SetVersionEIT(uint original_network_id, uint transport_stream_id,
121                       uint serviceid, uint tableid,
122                       int version, uint last_section)
123    {
124        if (VersionEIT(original_network_id, transport_stream_id,
125                       serviceid, tableid) == version)
126            return;
127
128        if (original_network_id == 0x233a)
129            original_network_id = GenerateUniqueUKOriginalNetworkID(transport_stream_id);
130
131        uint64_t key =
132                uint64_t(original_network_id) << 48 |
133                uint64_t(transport_stream_id)  << 32 |
134                serviceid << 16 | tableid;
135
136        _eit_version[key] = version;
137        init_sections(_eit_section_seen[key], last_section);
138    }
139
140    int VersionEIT(uint original_network_id, uint transport_stream_id,
141                   uint serviceid, uint tableid) const
142    {
143        if (original_network_id == 0x233a)
144            original_network_id = GenerateUniqueUKOriginalNetworkID(transport_stream_id);
145
146        uint64_t key =
147                uint64_t(original_network_id) << 48 |
148                uint64_t(transport_stream_id)  << 32 |
149                serviceid << 16 | tableid;
150
151        const QMap<uint64_t, int>::const_iterator it = _eit_version.find(key);
152        if (it == _eit_version.end())
153            return -1;
154        return *it;
155    }
156
157    void SetVersionBAT(uint bid, int version, uint last_section)
158    {
159        if (_bat_versions[bid] == version)
160            return;
161        _bat_versions[bid] = version;
162        init_sections(_bat_section_seen[bid], last_section);
163    }
164    int VersionBAT(uint bid) const
165    {
166        const QMap<uint, int>::const_iterator it = _bat_versions.find(bid);
167        if (it == _bat_versions.end())
168            return -1;
169        return *it;
170    }
171
172    // Premiere private ContentInformationTable
173    void SetVersionCIT(uint contentid, int version)
174    {
175        if (VersionCIT(contentid) == version)
176            return;
177        _cit_version[contentid] = version;
178    }
179
180    int VersionCIT(uint contentid) const
181    {
182        const QMap<uint, int>::const_iterator it = _cit_version.find(contentid);
183        if (it == _cit_version.end())
184            return -1;
185        return *it;
186    }
187
188    // Sections seen
189    void SetNITSectionSeen(uint section);
190    bool NITSectionSeen(uint section) const;
191    bool HasAllNITSections(void) const;
192
193    void SetNIToSectionSeen(uint section);
194    bool NIToSectionSeen(uint section) const;
195    bool HasAllNIToSections(void) const;
196
197    void SetSDTSectionSeen(uint tsid, uint section);
198    bool SDTSectionSeen(uint tsid, uint section) const;
199    bool HasAllSDTSections(uint tsid) const;
200
201    void SetSDToSectionSeen(uint tsid, uint section);
202    bool SDToSectionSeen(uint tsid, uint section) const;
203    bool HasAllSDToSections(uint tsid) const;
204
205    void SetEITSectionSeen(uint original_network_id, uint transport_stream_id,
206                           uint serviceid, uint tableid, uint section,
207                           uint segment_last_section);
208    bool EITSectionSeen(uint original_network_id, uint transport_stream_id,
209                        uint serviceid, uint tableid, uint section) const;
210    bool HasAllEITSections(uint original_network_id, uint transport_stream_id,
211                           uint serviceid, uint tableid) const;
212
213    void SetBATSectionSeen(uint bid, uint section);
214    bool BATSectionSeen(uint bid, uint section) const;
215    bool HasAllBATSections(uint bid) const;
216
217    // Premiere private ContentInformationTable
218    void SetCITSectionSeen(uint contentid, uint section);
219    bool CITSectionSeen(uint contentid, uint section) const;
220
221    // Caching
222    bool HasCachedAnyNIT(bool current = true) const;
223    bool HasCachedAllNIT(bool current = true) const;
224    bool HasCachedAnySDT(uint tsid, bool current = true) const;
225    bool HasCachedAllSDT(uint tsid, bool current = true) const;
226    bool HasCachedSDT(bool current = true) const;
227    bool HasCachedAnySDTs(bool current = true) const;
228    bool HasCachedAllSDTs(bool current = true) const;
229
230    nit_const_ptr_t GetCachedNIT(uint section_num, bool current = true) const;
231    nit_vec_t GetCachedNIT(bool current = true) const;
232    sdt_const_ptr_t GetCachedSDT(uint tsid, uint section_num,
233                           bool current = true) const;
234    sdt_vec_t GetCachedSDTs(bool current = true) const;
235
236    void ReturnCachedSDTTables(sdt_vec_t&) const;
237
238    void AddDVBMainListener(DVBMainStreamListener*);
239    void AddDVBOtherListener(DVBOtherStreamListener*);
240    void AddDVBEITListener(DVBEITStreamListener*);
241
242    void RemoveDVBMainListener(DVBMainStreamListener*);
243    void RemoveDVBOtherListener(DVBOtherStreamListener*);
244    void RemoveDVBEITListener(DVBEITStreamListener*);
245
246  private:
247    // Caching
248    void CacheNIT(NetworkInformationTable*);
249    void CacheSDT(ServiceDescriptionTable*);
250  protected:
251    virtual bool DeleteCachedTable(PSIPTable *psip) const;
252
253  private:
254    /// DVB table monitoring
255    uint                      _desired_netid;
256    uint                      _desired_tsid;
257
258    // Real network ID for broken providers
259    int                       _dvb_real_network_id;
260
261    /// Decode DishNet's long-term DVB EIT
262    bool                      _dvb_eit_dishnet_long;
263    /// Tell us if the DVB service has EIT
264    dvb_has_eit_t             _dvb_has_eit;
265
266    // Signals
267    dvb_main_listener_vec_t   _dvb_main_listeners;
268    dvb_other_listener_vec_t  _dvb_other_listeners;
269    dvb_eit_listener_vec_t    _dvb_eit_listeners;
270
271    // Table versions
272    int                       _nit_version;
273    QMap<uint, int>           _sdt_versions;
274    sections_t                _nit_section_seen;
275    sections_map_t            _sdt_section_seen;
276    QMap<uint64_t, int>       _eit_version;
277    QMap<uint64_t, sections_t> _eit_section_seen;
278    // Premiere private ContentInformationTable
279    QMap<uint, int>           _cit_version;
280    sections_map_t            _cit_section_seen;
281
282    int                       _nito_version;
283    QMap<uint, int>           _sdto_versions;
284    sections_t                _nito_section_seen;
285    sections_map_t            _sdto_section_seen;
286    QMap<uint, int>           _bat_versions;
287    sections_map_t            _bat_section_seen;
288
289    // Caching
290    mutable nit_cache_t       _cached_nit;  // section -> sdt
291    mutable sdt_cache_t       _cached_sdts; // tsid+section -> sdt
292};
293
294inline void DVBStreamData::SetDishNetEIT(bool use_dishnet_eit)
295{
296    QMutexLocker locker(&_listener_lock);
297    _dvb_eit_dishnet_long = use_dishnet_eit;
298}
299
300inline void DVBStreamData::SetRealNetworkID(int real_network_id)
301{
302    QMutexLocker locker(&_listener_lock);
303    _dvb_real_network_id = real_network_id;
304}
305
306inline bool DVBStreamData::HasAnyEIT(void) const
307{
308    QMutexLocker locker(&_listener_lock);
309    return _dvb_has_eit.size();
310}
311
312inline bool DVBStreamData::HasEIT(uint serviceid) const
313{
314    QMutexLocker locker(&_listener_lock);
315
316    dvb_has_eit_t::const_iterator it = _dvb_has_eit.find(serviceid);
317    if (it != _dvb_has_eit.end())
318        return *it;
319
320    return false;
321}
322
323#endif // DVBSTREAMDATA_H_