MythTV  master
mpegstreamdata.h
Go to the documentation of this file.
1 // -*- Mode: c++ -*-
2 // Copyright (c) 2003-2004, Daniel Thor Kristjansson
3 #ifndef MPEGSTREAMDATA_H_
4 #define MPEGSTREAMDATA_H_
5 
6 // C++
7 #include <cstdint> // uint64_t
8 #include <vector>
9 using namespace std;
10 
11 // Qt
12 #include <QMap>
13 
14 #include "tspacket.h"
15 #include "mythtimer.h"
16 #include "streamlisteners.h"
17 #include "eitscanner.h"
18 #include "mythtvexp.h"
19 #include "tablestatus.h"
20 
21 class EITHelper;
22 class PSIPTable;
23 class RingBuffer;
24 
25 using uint_vec_t = vector<uint>;
26 
27 using pid_psip_map_t = QMap<unsigned int, PSIPTable*>;
28 using psip_refcnt_map_t = QMap<const PSIPTable*, int>;
29 
32 using pat_vec_t = vector<const ProgramAssociationTable *>;
33 using pat_map_t = QMap<uint, pat_vec_t>;
34 using pat_cache_t = QMap<uint, ProgramAssociationTable*>;
35 
38 using cat_vec_t = vector<const ConditionalAccessTable *>;
39 using cat_map_t = QMap<uint, cat_vec_t>;
40 using cat_cache_t = QMap<uint, ConditionalAccessTable*>;
41 
44 using pmt_vec_t = vector<const ProgramMapTable*>;
45 using pmt_map_t = QMap<uint, pmt_vec_t>;
46 using pmt_cache_t = QMap<uint, ProgramMapTable*>;
47 
48 using uchar_vec_t = vector<unsigned char>;
49 
50 using mpeg_listener_vec_t = vector<MPEGStreamListener*>;
51 using ts_listener_vec_t = vector<TSPacketListener*>;
52 using ts_av_listener_vec_t = vector<TSPacketListenerAV*>;
53 using mpeg_sp_listener_vec_t = vector<MPEGSingleProgramStreamListener*>;
54 using ps_listener_vec_t = vector<PSStreamListener*>;
55 
57 {
61 };
62 
64 {
65  public:
66  CryptInfo() = default;
67  CryptInfo(uint e, uint d) : m_encryptedMin(e), m_decryptedMin(d) { }
68 
69  public:
71  uint m_encryptedPackets {0};
72  uint m_decryptedPackets {0};
73  uint m_encryptedMin {1000};
74  uint m_decryptedMin {8};
75 };
76 
78 {
83 };
84 using pid_map_t = QMap<uint, PIDPriority>;
85 
87 {
88  public:
89  MPEGStreamData(int desiredProgram, int cardnum, bool cacheTables);
90  ~MPEGStreamData() override;
91 
92  void SetCaching(bool cacheTables) { m_cacheTables = cacheTables; }
93  void SetListeningDisabled(bool lt) { m_listeningDisabled = lt; }
94 
95  virtual void Reset(void) { Reset(-1); }
96  virtual void Reset(int desiredProgram);
97 
99  double TimeOffset(void) const;
100 
101  // EIT Source
102  void SetEITHelper(EITHelper *eit_helper) override; // EITSource
103  void SetEITRate(float rate) override; // EITSource
104  virtual bool HasEITPIDChanges(const uint_vec_t& /*in_use_pids*/) const
105  { return false; }
106  virtual bool GetEITPIDChanges(const uint_vec_t& /*in_use_pids*/,
107  uint_vec_t& /*add_pids*/,
108  uint_vec_t& /*del_pids*/) const
109  { return false; }
110 
111  // Table processing
112  void SetIgnoreCRC(bool haveCRCbug) { m_haveCrcBug = haveCRCbug; }
113  virtual bool IsRedundant(uint pid, const PSIPTable &psip) const;
114  virtual bool HandleTables(uint pid, const PSIPTable &psip);
115  virtual void HandleTSTables(const TSPacket* tspacket);
116  virtual bool ProcessTSPacket(const TSPacket& tspacket);
117  virtual int ProcessData(const unsigned char *buffer, int len);
118  inline void HandleAdaptationFieldControl(const TSPacket* tspacket);
119 
120  // Listening
121  virtual void AddListeningPID(
122  uint pid, PIDPriority priority = kPIDPriorityNormal)
123  { m_pidsListening[pid] = priority; }
124  virtual void AddNotListeningPID(uint pid)
125  { m_pidsNotListening[pid] = kPIDPriorityNormal; }
126  virtual void AddWritingPID(
127  uint pid, PIDPriority priority = kPIDPriorityHigh)
128  { m_pidsWriting[pid] = priority; }
129  virtual void AddAudioPID(
130  uint pid, PIDPriority priority = kPIDPriorityHigh)
131  { m_pidsAudio[pid] = priority; }
132 
133  virtual void RemoveListeningPID(uint pid) { m_pidsListening.remove(pid); }
134  virtual void RemoveNotListeningPID(uint pid)
135  { m_pidsNotListening.remove(pid); }
136  virtual void RemoveWritingPID(uint pid) { m_pidsWriting.remove(pid); }
137  virtual void RemoveAudioPID(uint pid) { m_pidsAudio.remove(pid); }
138 
139  virtual bool IsListeningPID(uint pid) const;
140  virtual bool IsNotListeningPID(uint pid) const;
141  virtual bool IsWritingPID(uint pid) const;
142  bool IsVideoPID(uint pid) const
143  { return m_pidVideoSingleProgram == pid; }
144  virtual bool IsAudioPID(uint pid) const;
145 
146  const pid_map_t& ListeningPIDs(void) const
147  { return m_pidsListening; }
148  const pid_map_t& AudioPIDs(void) const
149  { return m_pidsAudio; }
150  const pid_map_t& WritingPIDs(void) const
151  { return m_pidsWriting; }
152 
153  uint GetPIDs(pid_map_t &pids) const;
154 
155  // PID Priorities
156  PIDPriority GetPIDPriority(uint pid) const;
157 
158  // Table versions
159  void SetVersionPAT(uint tsid, int version, uint last_section)
160  {
161  m_patStatus.SetVersion(tsid, version, last_section);
162  }
163  void SetVersionPMT(uint pnum, int version, uint last_section)
164  {
165  m_pmtStatus.SetVersion(pnum, version, last_section);
166  }
167 
168  // Sections seen
169  bool HasAllPATSections(uint tsid) const;
170 
171  bool HasAllCATSections(uint tsid) const;
172 
173  bool HasAllPMTSections(uint prog_num) const;
174 
175  // Caching
176  bool HasProgram(uint progNum) const;
177 
178  bool HasCachedAllPAT(uint tsid) const;
179  bool HasCachedAnyPAT(uint tsid) const;
180  bool HasCachedAnyPAT(void) const;
181 
182  bool HasCachedAllCAT(uint tsid) const;
183  bool HasCachedAnyCAT(uint tsid) const;
184  bool HasCachedAnyCAT(void) const;
185 
186  bool HasCachedAllPMT(uint pnum) const;
187  bool HasCachedAnyPMT(uint pnum) const;
188  bool HasCachedAllPMTs(void) const;
189  bool HasCachedAnyPMTs(void) const;
190 
191  pat_const_ptr_t GetCachedPAT(uint tsid, uint section_num) const;
192  pat_vec_t GetCachedPATs(uint tsid) const;
193  pat_vec_t GetCachedPATs(void) const;
194  pat_map_t GetCachedPATMap(void) const;
195 
196  cat_const_ptr_t GetCachedCAT(uint tsid, uint section_num) const;
197  cat_vec_t GetCachedCATs(uint tsid) const;
198  cat_vec_t GetCachedCATs(void) const;
199  cat_map_t GetCachedCATMap(void) const;
200 
201  pmt_const_ptr_t GetCachedPMT(uint program_num, uint section_num) const;
202  pmt_vec_t GetCachedPMTs(void) const;
203  pmt_map_t GetCachedPMTMap(void) const;
204 
205  virtual void ReturnCachedTable(const PSIPTable *psip) const;
206  virtual void ReturnCachedPATTables(pat_vec_t &pats) const;
207  virtual void ReturnCachedPATTables(pat_map_t &pats) const;
208  virtual void ReturnCachedCATTables(cat_vec_t &cats) const;
209  virtual void ReturnCachedCATTables(cat_map_t &cats) const;
210  virtual void ReturnCachedPMTTables(pmt_vec_t &pmts) const;
211  virtual void ReturnCachedPMTTables(pmt_map_t &pmts) const;
212 
213  // Encryption Monitoring
214  void AddEncryptionTestPID(uint pnum, uint pid, bool isvideo);
215  void RemoveEncryptionTestPIDs(uint pnum);
216  bool IsEncryptionTestPID(uint pid) const;
217 
218  void TestDecryption(const ProgramMapTable* pmt);
219  void ResetDecryptionMonitoringState(void);
220 
221  bool IsProgramDecrypted(uint pnum) const;
222  bool IsProgramEncrypted(uint pnum) const;
223 
224  // "signals"
225  void AddMPEGListener(MPEGStreamListener *val);
226  void RemoveMPEGListener(MPEGStreamListener *val);
227 
228  void AddWritingListener(TSPacketListener *val);
229  void RemoveWritingListener(TSPacketListener *val);
230 
231  // Single Program Stuff, signals with processed tables
232  void AddMPEGSPListener(MPEGSingleProgramStreamListener *val);
233  void RemoveMPEGSPListener(MPEGSingleProgramStreamListener *val);
234  void AddAVListener(TSPacketListenerAV *val);
235  void RemoveAVListener(TSPacketListenerAV *val);
236 
237  // Program Stream Stuff
238  void AddPSStreamListener(PSStreamListener *val);
239  void RemovePSStreamListener(PSStreamListener *val);
240 
241  public:
242  // Single program stuff, sets
243  void SetDesiredProgram(int p);
244  inline void SetPATSingleProgram(ProgramAssociationTable *pat);
245  inline void SetPMTSingleProgram(ProgramMapTable *pmt);
247  { m_pmtSingleProgramNumVideo = num; }
249  { return m_pmtSingleProgramNumVideo; }
251  { m_pmtSingleProgramNumAudio = num; }
253  { return m_pmtSingleProgramNumAudio; }
254  void SetRecordingType(const QString &recording_type);
255 
256  // Single program stuff, gets
257  int DesiredProgram(void) const { return m_desiredProgram; }
258  uint VideoPIDSingleProgram(void) const { return m_pidVideoSingleProgram; }
259  QString GetRecordingType(void) const { return m_recordingType; }
260 
262  { return m_patSingleProgram; }
264  { return m_pmtSingleProgram; }
265 
267  { return m_patSingleProgram; }
269  { return m_pmtSingleProgram; }
270 
271  // Single program stuff, mostly used internally
272  int VersionPATSingleProgram(void) const;
273  int VersionPMTSingleProgram(void) const;
274 
275  bool CreatePATSingleProgram(const ProgramAssociationTable &pat);
276  bool CreatePMTSingleProgram(const ProgramMapTable &pmt);
277 
278  protected:
279  // Table processing -- for internal use
280  PSIPTable* AssemblePSIP(const TSPacket* tspacket, bool& moreTablePackets);
281  bool AssemblePSIP(PSIPTable& psip, TSPacket* tspacket);
282  void SavePartialPSIP(uint pid, PSIPTable* packet);
284  { return m_partialPsipPacketCache[pid]; }
286  { m_partialPsipPacketCache.remove(pid); }
287  void DeletePartialPSIP(uint pid);
288  void ProcessPAT(const ProgramAssociationTable *pat);
289  void ProcessCAT(const ConditionalAccessTable *cat);
290  void ProcessPMT(const ProgramMapTable *pmt);
291  void ProcessEncryptedPacket(const TSPacket &tspacket);
292 
293  static int ResyncStream(const unsigned char *buffer, int curr_pos, int len);
294 
295  void UpdateTimeOffset(uint64_t si_utc_time);
296 
297  // Caching
298  void IncrementRefCnt(const PSIPTable *psip) const;
299  virtual bool DeleteCachedTable(const PSIPTable *psip) const;
300  void CachePAT(const ProgramAssociationTable *pat);
301  void CacheCAT(const ConditionalAccessTable *_cat);
302  void CachePMT(const ProgramMapTable *pmt);
303 
304  protected:
305  int m_cardId;
306  QString m_siStandard {"mpeg"};
307 
308  bool m_haveCrcBug {false};
309 
310  mutable QMutex m_siTimeLock;
311  uint m_siTimeOffsetCnt {0};
312  uint m_siTimeOffsetIndx {0};
313  double m_siTimeOffsets[16] {0.0};
314 
315  // Generic EIT stuff used for ATSC and DVB
316  EITHelper *m_eitHelper {nullptr};
317  float m_eitRate {0.0F};
318 
319  // Listening
324  bool m_listeningDisabled {false};
325 
326  // Encryption monitoring
327  mutable QMutex m_encryptionLock {QMutex::Recursive};
328  QMap<uint, CryptInfo> m_encryptionPidToInfo;
329  QMap<uint, uint_vec_t> m_encryptionPnumToPids;
330  QMap<uint, uint_vec_t> m_encryptionPidToPnums;
331  QMap<uint, CryptStatus> m_encryptionPnumToStatus;
332 
333  // Signals
334  mutable QMutex m_listenerLock {QMutex::Recursive};
340 
341  // Table versions
345 
346  // PSIP construction
348 
349  // Caching
351  mutable QMutex m_cacheLock {QMutex::Recursive};
357 
358  // Single program variables
360  QString m_recordingType {"all"};
361  bool m_stripPmtDescriptors {false};
362  bool m_normalizeStreamType {true};
363  uint m_pidVideoSingleProgram {0xffffffff};
364  uint m_pidPmtSingleProgram {0xffffffff};
365  uint m_pmtSingleProgramNumVideo {1};
366  uint m_pmtSingleProgramNumAudio {0};
367  ProgramAssociationTable *m_patSingleProgram {nullptr};
368  ProgramMapTable *m_pmtSingleProgram {nullptr};
369 
370  // PAT Timeout handling.
371  private:
372  bool m_invalidPatSeen {false};
373  bool m_invalidPatWarning {false};
375 };
376 
377 #include "mpegtables.h"
378 
380 {
381  delete m_patSingleProgram;
382  m_patSingleProgram = pat;
383 }
384 
386 {
387  delete m_pmtSingleProgram;
388  m_pmtSingleProgram = pmt;
389 }
390 
392 {
393  return (m_patSingleProgram) ? int(m_patSingleProgram->Version()) : -1;
394 }
395 
397 {
398  return (m_pmtSingleProgram) ? int(m_pmtSingleProgram->Version()) : -1;
399 }
400 
402 {
403  // TODO
404  //AdaptationFieldControl afc(tspacket.data()+4);
405 }
406 
407 #endif
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
QString GetRecordingType(void) const
mpeg_listener_vec_t m_mpegListeners
vector< unsigned char > uchar_vec_t
void SetVideoStreamsRequired(uint num)
const ProgramAssociationTable * PATSingleProgram(void) const
virtual void Reset(void)
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
int VersionPMTSingleProgram(void) const
TableStatusMap m_catStatus
void SetPMTSingleProgram(ProgramMapTable *pmt)
psip_refcnt_map_t m_cachedSlatedForDeletion
virtual void AddNotListeningPID(uint pid)
ProgramMapTable * PMTSingleProgram(void)
QMap< uint, ConditionalAccessTable * > cat_cache_t
mpeg_sp_listener_vec_t m_mpegSpListeners
QMap< uint, ProgramMapTable * > pmt_cache_t
QMap< uint, pmt_vec_t > pmt_map_t
QMap< uint, uint_vec_t > m_encryptionPidToPnums
vector< MPEGStreamListener * > mpeg_listener_vec_t
QMap< uint, pat_vec_t > pat_map_t
int DesiredProgram(void) const
ProgramMapTable const * pmt_const_ptr_t
uint GetVideoStreamsRequired() const
ts_listener_vec_t m_tsWritingListeners
vector< uint > uint_vec_t
pat_cache_t m_cachedPats
QMap< uint, PIDPriority > pid_map_t
pmt_cache_t m_cachedPmts
virtual void RemoveNotListeningPID(uint pid)
QMap< uint, ProgramAssociationTable * > pat_cache_t
PSIPTable * GetPartialPSIP(uint pid)
void SetVersionPMT(uint pnum, int version, uint last_section)
ps_listener_vec_t m_psListeners
vector< const ProgramMapTable * > pmt_vec_t
const pid_map_t & ListeningPIDs(void) const
virtual void RemoveListeningPID(uint pid)
void SetAudioStreamsRequired(uint num)
ProgramAssociationTable * PATSingleProgram(void)
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:386
void ClearPartialPSIP(uint pid)
virtual void RemoveAudioPID(uint pid)
#define MTV_PUBLIC
Definition: mythtvexp.h:15
CryptStatus
The CAT is used to transmit additional ConditionalAccessDescriptor instances, in addition to the ones...
Definition: mpegtables.h:828
static const uint16_t * d
uint GetAudioStreamsRequired() const
vector< const ProgramAssociationTable * > pat_vec_t
int VersionPATSingleProgram(void) const
void SetPATSingleProgram(ProgramAssociationTable *pat)
bool IsVideoPID(uint pid) const
pid_psip_map_t m_partialPsipPacketCache
vector< TSPacketListener * > ts_listener_vec_t
unsigned int uint
Definition: compat.h:140
void SetIgnoreCRC(bool haveCRCbug)
TableStatusMap m_pmtStatus
pid_map_t m_pidsListening
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:589
virtual void AddAudioPID(uint pid, PIDPriority priority=kPIDPriorityHigh)
pid_map_t m_pidsAudio
TableStatusMap m_patStatus
QMap< const PSIPTable *, int > psip_refcnt_map_t
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
psip_refcnt_map_t m_cachedRefCnt
vector< PSStreamListener * > ps_listener_vec_t
PIDPriority
void SetVersionPAT(uint tsid, int version, uint last_section)
void SetCaching(bool cacheTables)
const ProgramMapTable * PMTSingleProgram(void) const
QMap< uint, cat_vec_t > cat_map_t
const pid_map_t & AudioPIDs(void) const
uint VideoPIDSingleProgram(void) const
vector< const ConditionalAccessTable * > cat_vec_t
void SetListeningDisabled(bool lt)
virtual void RemoveWritingPID(uint pid)
vector< TSPacketListenerAV * > ts_av_listener_vec_t
virtual void AddWritingPID(uint pid, PIDPriority priority=kPIDPriorityHigh)
vector< MPEGSingleProgramStreamListener * > mpeg_sp_listener_vec_t
pid_map_t m_pidsWriting
virtual bool HasEITPIDChanges(const uint_vec_t &) const
MythTimer m_invalidPatTimer
Implements a file/stream reader/writer.
ts_av_listener_vec_t m_tsAvListeners
QMap< uint, CryptInfo > m_encryptionPidToInfo
CryptInfo(uint e, uint d)
QMap< uint, CryptStatus > m_encryptionPnumToStatus
QMap< unsigned int, PSIPTable * > pid_psip_map_t
void HandleAdaptationFieldControl(const TSPacket *tspacket)
pid_map_t m_pidsNotListening
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:666
QMap< uint, uint_vec_t > m_encryptionPnumToPids
virtual bool GetEITPIDChanges(const uint_vec_t &, uint_vec_t &, uint_vec_t &) const
const pid_map_t & WritingPIDs(void) const
Encapsulates data about MPEG stream and emits events for each table.
cat_cache_t m_cachedCats