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 typedef vector<uint> uint_vec_t;
26 
27 typedef QMap<unsigned int, PSIPTable*> pid_psip_map_t;
28 typedef QMap<const PSIPTable*, int> psip_refcnt_map_t;
29 
32 typedef vector<const ProgramAssociationTable*> pat_vec_t;
33 typedef QMap<uint, pat_vec_t> pat_map_t;
34 typedef QMap<uint, ProgramAssociationTable*> pat_cache_t;
35 
38 typedef vector<const ConditionalAccessTable*> cat_vec_t;
39 typedef QMap<uint, cat_vec_t> cat_map_t;
40 typedef QMap<uint, ConditionalAccessTable*> cat_cache_t;
41 
44 typedef vector<const ProgramMapTable*> pmt_vec_t;
45 typedef QMap<uint, pmt_vec_t> pmt_map_t;
46 typedef QMap<uint, ProgramMapTable*> pmt_cache_t;
47 
48 typedef vector<unsigned char> uchar_vec_t;
49 
50 typedef vector<MPEGStreamListener*> mpeg_listener_vec_t;
51 typedef vector<TSPacketListener*> ts_listener_vec_t;
52 typedef vector<TSPacketListenerAV*> ts_av_listener_vec_t;
53 typedef vector<MPEGSingleProgramStreamListener*> mpeg_sp_listener_vec_t;
54 typedef vector<PSStreamListener*> ps_listener_vec_t;
55 
56 typedef enum
57 {
61 } CryptStatus;
62 
64 {
65  public:
67  status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
68  encrypted_min(1000), decrypted_min(8) { }
70  status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
71  encrypted_min(e), decrypted_min(d) { }
72 
73  public:
79 };
80 
81 typedef enum
82 {
87 } PIDPriority;
88 typedef QMap<uint, PIDPriority> pid_map_t;
89 
91 {
92  public:
93  MPEGStreamData(int desiredProgram, int cardnum, bool cacheTables);
94  virtual ~MPEGStreamData();
95 
96  void SetCaching(bool cacheTables) { _cache_tables = cacheTables; }
97  void SetListeningDisabled(bool lt) { _listening_disabled = lt; }
98 
99  virtual void Reset(void) { Reset(-1); }
100  virtual void Reset(int desiredProgram);
101 
103  double TimeOffset(void) const;
104 
105  // EIT Source
106  void SetEITHelper(EITHelper *eit_helper) override; // EITSource
107  void SetEITRate(float rate) override; // EITSource
108  virtual bool HasEITPIDChanges(const uint_vec_t& /*in_use_pids*/) const
109  { return false; }
110  virtual bool GetEITPIDChanges(const uint_vec_t& /*in_use_pids*/,
111  uint_vec_t& /*add_pids*/,
112  uint_vec_t& /*del_pids*/) const
113  { return false; }
114 
115  // Table processin
116  void SetIgnoreCRC(bool haveCRCbug) { _have_CRC_bug = haveCRCbug; }
117  virtual bool IsRedundant(uint pid, const PSIPTable&) const;
118  virtual bool HandleTables(uint pid, const PSIPTable &psip);
119  virtual void HandleTSTables(const TSPacket* tspacket);
120  virtual bool ProcessTSPacket(const TSPacket& tspacket);
121  virtual int ProcessData(const unsigned char *buffer, int len);
122  inline void HandleAdaptationFieldControl(const TSPacket* tspacket);
123 
124  // Listening
125  virtual void AddListeningPID(
126  uint pid, PIDPriority priority = kPIDPriorityNormal)
127  { _pids_listening[pid] = priority; }
128  virtual void AddNotListeningPID(uint pid)
129  { _pids_notlistening[pid] = kPIDPriorityNormal; }
130  virtual void AddWritingPID(
131  uint pid, PIDPriority priority = kPIDPriorityHigh)
132  { _pids_writing[pid] = priority; }
133  virtual void AddAudioPID(
134  uint pid, PIDPriority priority = kPIDPriorityHigh)
135  { _pids_audio[pid] = priority; }
136 
137  virtual void RemoveListeningPID(uint pid) { _pids_listening.remove(pid); }
138  virtual void RemoveNotListeningPID(uint pid)
139  { _pids_notlistening.remove(pid); }
140  virtual void RemoveWritingPID(uint pid) { _pids_writing.remove(pid); }
141  virtual void RemoveAudioPID(uint pid) { _pids_audio.remove(pid); }
142 
143  virtual bool IsListeningPID(uint pid) const;
144  virtual bool IsNotListeningPID(uint pid) const;
145  virtual bool IsWritingPID(uint pid) const;
146  bool IsVideoPID(uint pid) const
147  { return _pid_video_single_program == pid; }
148  virtual bool IsAudioPID(uint pid) const;
149 
150  const pid_map_t& ListeningPIDs(void) const
151  { return _pids_listening; }
152  const pid_map_t& AudioPIDs(void) const
153  { return _pids_audio; }
154  const pid_map_t& WritingPIDs(void) const
155  { return _pids_writing; }
156 
157  uint GetPIDs(pid_map_t&) const;
158 
159  // PID Priorities
160  PIDPriority GetPIDPriority(uint pid) const;
161 
162  // Table versions
163  void SetVersionPAT(uint tsid, int version, uint last_section)
164  {
165  _pat_status.SetVersion(tsid, version, last_section);
166  }
167  void SetVersionPMT(uint pnum, int version, uint last_section)
168  {
169  _pmt_status.SetVersion(pnum, version, last_section);
170  }
171 
172  // Sections seen
173  bool HasAllPATSections(uint tsid) const;
174 
175  bool HasAllCATSections(uint tsid) const;
176 
177  bool HasAllPMTSections(uint prog_num) const;
178 
179  // Caching
180  bool HasProgram(uint progNum) const;
181 
182  bool HasCachedAllPAT(uint tsid) const;
183  bool HasCachedAnyPAT(uint tsid) const;
184  bool HasCachedAnyPAT(void) const;
185 
186  bool HasCachedAllCAT(uint tsid) const;
187  bool HasCachedAnyCAT(uint tsid) const;
188  bool HasCachedAnyCAT(void) const;
189 
190  bool HasCachedAllPMT(uint pnum) const;
191  bool HasCachedAnyPMT(uint pnum) const;
192  bool HasCachedAllPMTs(void) const;
193  bool HasCachedAnyPMTs(void) const;
194 
195  pat_const_ptr_t GetCachedPAT(uint tsid, uint section_num) const;
196  pat_vec_t GetCachedPATs(uint tsid) const;
197  pat_vec_t GetCachedPATs(void) const;
198  pat_map_t GetCachedPATMap(void) const;
199 
200  cat_const_ptr_t GetCachedCAT(uint tsid, uint section_num) const;
201  cat_vec_t GetCachedCATs(uint tsid) const;
202  cat_vec_t GetCachedCATs(void) const;
203  cat_map_t GetCachedCATMap(void) const;
204 
205  pmt_const_ptr_t GetCachedPMT(uint program_num, uint section_num) const;
206  pmt_vec_t GetCachedPMTs(void) const;
207  pmt_map_t GetCachedPMTMap(void) const;
208 
209  virtual void ReturnCachedTable(const PSIPTable *psip) const;
210  virtual void ReturnCachedPATTables(pat_vec_t&) const;
211  virtual void ReturnCachedPATTables(pat_map_t&) const;
212  virtual void ReturnCachedCATTables(cat_vec_t&) const;
213  virtual void ReturnCachedCATTables(cat_map_t&) const;
214  virtual void ReturnCachedPMTTables(pmt_vec_t&) const;
215  virtual void ReturnCachedPMTTables(pmt_map_t&) const;
216 
217  // Encryption Monitoring
218  void AddEncryptionTestPID(uint pnum, uint pid, bool isvideo);
219  void RemoveEncryptionTestPIDs(uint pnum);
220  bool IsEncryptionTestPID(uint pid) const;
221 
222  void TestDecryption(const ProgramMapTable* pmt);
223  void ResetDecryptionMonitoringState(void);
224 
225  bool IsProgramDecrypted(uint pnum) const;
226  bool IsProgramEncrypted(uint pnum) const;
227 
228  // "signals"
229  void AddMPEGListener(MPEGStreamListener*);
230  void RemoveMPEGListener(MPEGStreamListener*);
231  void UpdatePAT(const ProgramAssociationTable*);
232  void UpdateCAT(const ConditionalAccessTable*);
233  void UpdatePMT(uint program_num, const ProgramMapTable*);
234 
235  void AddWritingListener(TSPacketListener*);
236  void RemoveWritingListener(TSPacketListener*);
237 
238  // Single Program Stuff, signals with processed tables
239  void AddMPEGSPListener(MPEGSingleProgramStreamListener*);
240  void RemoveMPEGSPListener(MPEGSingleProgramStreamListener*);
241  void AddAVListener(TSPacketListenerAV*);
242  void RemoveAVListener(TSPacketListenerAV*);
243  void UpdatePATSingleProgram(ProgramAssociationTable*);
244  void UpdatePMTSingleProgram(ProgramMapTable*);
245 
246  // Program Stream Stuff
247  void AddPSStreamListener(PSStreamListener *val);
248  void RemovePSStreamListener(PSStreamListener *val);
249 
250  public:
251  // Single program stuff, sets
252  void SetDesiredProgram(int p);
253  inline void SetPATSingleProgram(ProgramAssociationTable*);
254  inline void SetPMTSingleProgram(ProgramMapTable*);
256  { _pmt_single_program_num_video = num; }
258  { return _pmt_single_program_num_video; }
260  { _pmt_single_program_num_audio = num; }
262  { return _pmt_single_program_num_audio; }
263  void SetRecordingType(const QString &recording_type);
264 
265  // Single program stuff, gets
266  int DesiredProgram(void) const { return _desired_program; }
267  uint VideoPIDSingleProgram(void) const { return _pid_video_single_program; }
268  QString GetRecordingType(void) const { return _recording_type; }
269 
271  { return _pat_single_program; }
273  { return _pmt_single_program; }
274 
276  { return _pat_single_program; }
278  { return _pmt_single_program; }
279 
280  // Single program stuff, mostly used internally
281  int VersionPATSingleProgram(void) const;
282  int VersionPMTSingleProgram(void) const;
283 
284  bool CreatePATSingleProgram(const ProgramAssociationTable&);
285  bool CreatePMTSingleProgram(const ProgramMapTable&);
286 
287  protected:
288  // Table processing -- for internal use
289  PSIPTable* AssemblePSIP(const TSPacket* tspacket, bool& moreTablePackets);
290  bool AssemblePSIP(PSIPTable& psip, TSPacket* tspacket);
291  void SavePartialPSIP(uint pid, PSIPTable* packet);
293  { return _partial_psip_packet_cache[pid]; }
295  { _partial_psip_packet_cache.remove(pid); }
296  void DeletePartialPSIP(uint pid);
297  void ProcessPAT(const ProgramAssociationTable *pat);
298  void ProcessCAT(const ConditionalAccessTable *cat);
299  void ProcessPMT(const ProgramMapTable *pmt);
300  void ProcessEncryptedPacket(const TSPacket&);
301 
302  static int ResyncStream(const unsigned char *buffer, int curr_pos, int len);
303 
304  void UpdateTimeOffset(uint64_t si_utc_time);
305 
306  // Caching
307  void IncrementRefCnt(const PSIPTable *psip) const;
308  virtual bool DeleteCachedTable(PSIPTable *psip) const;
309  void CachePAT(const ProgramAssociationTable *pat);
310  void CacheCAT(const ConditionalAccessTable *_cat);
311  void CachePMT(const ProgramMapTable *pmt);
312 
313  protected:
314  int _cardid;
315  QString _sistandard {"mpeg"};
316 
317  bool _have_CRC_bug {false};
318 
319  mutable QMutex _si_time_lock;
320  uint _si_time_offset_cnt {0};
321  uint _si_time_offset_indx {0};
322  double _si_time_offsets[16] {0.0};
323 
324  // Generic EIT stuff used for ATSC and DVB
325  EITHelper *_eit_helper {nullptr};
326  float _eit_rate {0.0F};
327 
328  // Listening
333  bool _listening_disabled {false};
334 
335  // Encryption monitoring
336  mutable QMutex _encryption_lock {QMutex::Recursive};
337  QMap<uint, CryptInfo> _encryption_pid_to_info;
338  QMap<uint, uint_vec_t> _encryption_pnum_to_pids;
339  QMap<uint, uint_vec_t> _encryption_pid_to_pnums;
340  QMap<uint, CryptStatus> _encryption_pnum_to_status;
341 
342  // Signals
343  mutable QMutex _listener_lock {QMutex::Recursive};
349 
350  // Table versions
354 
355  // PSIP construction
357 
358  // Caching
360  mutable QMutex _cache_lock {QMutex::Recursive};
366 
367  // Single program variables
369  QString _recording_type {"all"};
370  bool _strip_pmt_descriptors {false};
371  bool _normalize_stream_type {true};
372  uint _pid_video_single_program {0xffffffff};
373  uint _pid_pmt_single_program {0xffffffff};
374  uint _pmt_single_program_num_video {1};
375  uint _pmt_single_program_num_audio {0};
376  ProgramAssociationTable *_pat_single_program {nullptr};
377  ProgramMapTable *_pmt_single_program {nullptr};
378 
379  // PAT Timeout handling.
380  private:
381  bool _invalid_pat_seen {false};
382  bool _invalid_pat_warning {false};
384 };
385 
386 #include "mpegtables.h"
387 
389 {
390  if (_pat_single_program)
391  delete _pat_single_program;
392  _pat_single_program = pat;
393 }
394 
396 {
397  if (_pmt_single_program)
398  delete _pmt_single_program;
399  _pmt_single_program = pmt;
400 }
401 
403 {
404  return (_pat_single_program) ? int(_pat_single_program->Version()) : -1;
405 }
406 
408 {
409  return (_pmt_single_program) ? int(_pmt_single_program->Version()) : -1;
410 }
411 
413 {
414  // TODO
415  //AdaptationFieldControl afc(tspacket.data()+4);
416 }
417 
418 #endif
Used to access the data of a Transport Stream packet.
Definition: tspacket.h:166
ts_av_listener_vec_t _ts_av_listeners
QString GetRecordingType(void) const
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
ConditionalAccessTable * cat_ptr_t
int VersionPMTSingleProgram(void) const
virtual void AddNotListeningPID(uint pid)
ProgramAssociationTable const * pat_const_ptr_t
ProgramMapTable * PMTSingleProgram(void)
uint decrypted_min
QMap< const PSIPTable *, int > psip_refcnt_map_t
QMap< uint, PIDPriority > pid_map_t
vector< unsigned char > uchar_vec_t
QMap< uint, CryptStatus > _encryption_pnum_to_status
ps_listener_vec_t _ps_listeners
ConditionalAccessTable const * cat_const_ptr_t
vector< const ConditionalAccessTable * > cat_vec_t
unsigned int uint
Definition: compat.h:140
QMap< uint, pmt_vec_t > pmt_map_t
int DesiredProgram(void) const
vector< TSPacketListener * > ts_listener_vec_t
pmt_cache_t _cached_pmts
psip_refcnt_map_t _cached_ref_cnt
uint GetVideoStreamsRequired() const
pat_cache_t _cached_pats
virtual void RemoveNotListeningPID(uint pid)
PSIPTable * GetPartialPSIP(uint pid)
cat_cache_t _cached_cats
pid_psip_map_t _partial_psip_packet_cache
void SetVersionPMT(uint pnum, int version, uint last_section)
const pid_map_t & ListeningPIDs(void) const
virtual void RemoveListeningPID(uint pid)
void SetAudioStreamsRequired(uint num)
TableStatusMap _pmt_status
ProgramMapTable const * pmt_const_ptr_t
vector< MPEGStreamListener * > mpeg_listener_vec_t
ProgramAssociationTable * pat_ptr_t
ProgramAssociationTable * PATSingleProgram(void)
A PSIP table is a variant of a PES packet containing an MPEG, ATSC or DVB table.
Definition: mpegtables.h:371
void ClearPartialPSIP(uint pid)
virtual void RemoveAudioPID(uint pid)
CryptStatus status
#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:818
void SetPATSingleProgram(ProgramAssociationTable *)
static const uint16_t * d
uint GetAudioStreamsRequired() const
QMap< uint, ProgramMapTable * > pmt_cache_t
int VersionPATSingleProgram(void) const
void SetPMTSingleProgram(ProgramMapTable *)
MythTimer _invalid_pat_timer
psip_refcnt_map_t _cached_slated_for_deletion
bool IsVideoPID(uint pid) const
pid_map_t _pids_listening
QMap< uint, pat_vec_t > pat_map_t
pid_map_t _pids_audio
void SetIgnoreCRC(bool haveCRCbug)
The Program Association Table lists all the programs in a stream, and is always found on PID 0.
Definition: mpegtables.h:579
pid_map_t _pids_notlistening
virtual void AddAudioPID(uint pid, PIDPriority priority=kPIDPriorityHigh)
QMap< unsigned int, PSIPTable * > pid_psip_map_t
vector< uint > uint_vec_t
QMap< uint, ProgramAssociationTable * > pat_cache_t
virtual void AddListeningPID(uint pid, PIDPriority priority=kPIDPriorityNormal)
QMap< uint, pmt_vec_t > pmt_map_t
QMap< uint, uint_vec_t > _encryption_pid_to_pnums
PIDPriority
void SetVersionPAT(uint tsid, int version, uint last_section)
ProgramMapTable * pmt_ptr_t
void SetCaching(bool cacheTables)
vector< const ProgramMapTable * > pmt_vec_t
const ProgramMapTable * PMTSingleProgram(void) const
const pid_map_t & AudioPIDs(void) const
uint encrypted_min
uint VideoPIDSingleProgram(void) const
vector< const ProgramAssociationTable * > pat_vec_t
void SetListeningDisabled(bool lt)
virtual void RemoveWritingPID(uint pid)
virtual void AddWritingPID(uint pid, PIDPriority priority=kPIDPriorityHigh)
vector< TSPacketListenerAV * > ts_av_listener_vec_t
virtual bool HasEITPIDChanges(const uint_vec_t &) const
Implements a file/stream reader/writer.
QMap< uint, ConditionalAccessTable * > cat_cache_t
CryptInfo(uint e, uint d)
ts_listener_vec_t _ts_writing_listeners
vector< PSStreamListener * > ps_listener_vec_t
void HandleAdaptationFieldControl(const TSPacket *tspacket)
A PMT table maps a program described in the ProgramAssociationTable to various PID's which describe t...
Definition: mpegtables.h:656
virtual bool GetEITPIDChanges(const uint_vec_t &, uint_vec_t &, uint_vec_t &) const
QMap< uint, uint_vec_t > _encryption_pnum_to_pids
vector< MPEGSingleProgramStreamListener * > mpeg_sp_listener_vec_t
uint encrypted_packets
const pid_map_t & WritingPIDs(void) const
Encapsulates data about MPEG stream and emits events for each table.
mpeg_sp_listener_vec_t _mpeg_sp_listeners
uint decrypted_packets
pid_map_t _pids_writing
mpeg_listener_vec_t _mpeg_listeners
QMap< uint, CryptInfo > _encryption_pid_to_info
vector< const ProgramMapTable * > pmt_vec_t
QMap< uint, cat_vec_t > cat_map_t
TableStatusMap _cat_status
TableStatusMap _pat_status