00001
00002
00003 #ifndef MPEGSTREAMDATA_H_
00004 #define MPEGSTREAMDATA_H_
00005
00006
00007 #include <stdint.h>
00008
00009
00010 #include <vector>
00011 using namespace std;
00012
00013
00014 #include <QMap>
00015
00016 #include "tspacket.h"
00017 #include "mythmiscutil.h"
00018 #include "streamlisteners.h"
00019 #include "eitscanner.h"
00020 #include "mythtvexp.h"
00021
00022 class EITHelper;
00023 class PSIPTable;
00024 class RingBuffer;
00025
00026 typedef vector<uint> uint_vec_t;
00027
00028 typedef QMap<unsigned int, PSIPTable*> pid_psip_map_t;
00029 typedef QMap<const PSIPTable*, int> psip_refcnt_map_t;
00030
00031 typedef ProgramAssociationTable* pat_ptr_t;
00032 typedef vector<const ProgramAssociationTable*> pat_vec_t;
00033 typedef QMap<uint, pat_vec_t> pat_map_t;
00034 typedef QMap<uint, ProgramAssociationTable*> pat_cache_t;
00035
00036 typedef ConditionalAccessTable* cat_ptr_t;
00037 typedef vector<const ConditionalAccessTable*> cat_vec_t;
00038 typedef QMap<uint, cat_vec_t> cat_map_t;
00039 typedef QMap<uint, ConditionalAccessTable*> cat_cache_t;
00040
00041 typedef ProgramMapTable* pmt_ptr_t;
00042 typedef vector<const ProgramMapTable*> pmt_vec_t;
00043 typedef QMap<uint, pmt_vec_t> pmt_map_t;
00044 typedef QMap<uint, ProgramMapTable*> pmt_cache_t;
00045
00046 typedef vector<unsigned char> uchar_vec_t;
00047 typedef uchar_vec_t sections_t;
00048 typedef QMap<uint, sections_t> sections_map_t;
00049
00050 typedef vector<MPEGStreamListener*> mpeg_listener_vec_t;
00051 typedef vector<TSPacketListener*> ts_listener_vec_t;
00052 typedef vector<TSPacketListenerAV*> ts_av_listener_vec_t;
00053 typedef vector<MPEGSingleProgramStreamListener*> mpeg_sp_listener_vec_t;
00054
00055 typedef enum
00056 {
00057 kEncUnknown = 0,
00058 kEncDecrypted = 1,
00059 kEncEncrypted = 2,
00060 } CryptStatus;
00061
00062 class MTV_PUBLIC CryptInfo
00063 {
00064 public:
00065 CryptInfo() :
00066 status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
00067 encrypted_min(1000), decrypted_min(8) { }
00068 CryptInfo(uint e, uint d) :
00069 status(kEncUnknown), encrypted_packets(0), decrypted_packets(0),
00070 encrypted_min(e), decrypted_min(d) { }
00071
00072 public:
00073 CryptStatus status;
00074 uint encrypted_packets;
00075 uint decrypted_packets;
00076 uint encrypted_min;
00077 uint decrypted_min;
00078 };
00079
00080 void init_sections(sections_t §, uint last_section);
00081
00082 typedef enum
00083 {
00084 kPIDPriorityNone = 0,
00085 kPIDPriorityLow = 1,
00086 kPIDPriorityNormal = 2,
00087 kPIDPriorityHigh = 3,
00088 } PIDPriority;
00089 typedef QMap<uint, PIDPriority> pid_map_t;
00090
00091 class MTV_PUBLIC MPEGStreamData : public EITSource
00092 {
00093 public:
00094 MPEGStreamData(int desiredProgram, bool cacheTables);
00095 virtual ~MPEGStreamData();
00096
00097 void SetCaching(bool cacheTables) { _cache_tables = cacheTables; }
00098 void SetListeningDisabled(bool lt) { _listening_disabled = lt; }
00099
00100 virtual void Reset(void) { Reset(-1); }
00101 virtual void Reset(int desiredProgram);
00102
00104 double TimeOffset(void) const;
00105
00106
00107 virtual void SetEITHelper(EITHelper *eit_helper);
00108 virtual void SetEITRate(float rate);
00109 virtual bool HasEITPIDChanges(const uint_vec_t& ) const
00110 { return false; }
00111 virtual bool GetEITPIDChanges(const uint_vec_t& ,
00112 uint_vec_t& ,
00113 uint_vec_t& ) const
00114 { return false; }
00115
00116
00117 void SetIgnoreCRC(bool haveCRCbug) { _have_CRC_bug = haveCRCbug; }
00118 virtual bool IsRedundant(uint pid, const PSIPTable&) const;
00119 virtual bool HandleTables(uint pid, const PSIPTable &psip);
00120 virtual void HandleTSTables(const TSPacket* tspacket);
00121 virtual bool ProcessTSPacket(const TSPacket& tspacket);
00122 virtual int ProcessData(const unsigned char *buffer, int len);
00123 inline void HandleAdaptationFieldControl(const TSPacket* tspacket);
00124
00125
00126 virtual void AddListeningPID(
00127 uint pid, PIDPriority priority = kPIDPriorityNormal)
00128 { _pids_listening[pid] = priority; }
00129 virtual void AddNotListeningPID(uint pid)
00130 { _pids_notlistening[pid] = kPIDPriorityNormal; }
00131 virtual void AddWritingPID(
00132 uint pid, PIDPriority priority = kPIDPriorityHigh)
00133 { _pids_writing[pid] = priority; }
00134 virtual void AddAudioPID(
00135 uint pid, PIDPriority priority = kPIDPriorityHigh)
00136 { _pids_audio[pid] = priority; }
00137
00138 virtual void RemoveListeningPID(uint pid) { _pids_listening.remove(pid); }
00139 virtual void RemoveNotListeningPID(uint pid)
00140 { _pids_notlistening.remove(pid); }
00141 virtual void RemoveWritingPID(uint pid) { _pids_writing.remove(pid); }
00142 virtual void RemoveAudioPID(uint pid) { _pids_audio.remove(pid); }
00143
00144 virtual bool IsListeningPID(uint pid) const;
00145 virtual bool IsNotListeningPID(uint pid) const;
00146 virtual bool IsWritingPID(uint pid) const;
00147 bool IsVideoPID(uint pid) const
00148 { return _pid_video_single_program == pid; }
00149 virtual bool IsAudioPID(uint pid) const;
00150
00151 const pid_map_t& ListeningPIDs(void) const
00152 { return _pids_listening; }
00153 const pid_map_t& AudioPIDs(void) const
00154 { return _pids_audio; }
00155 const pid_map_t& WritingPIDs(void) const
00156 { return _pids_writing; }
00157
00158 uint GetPIDs(pid_map_t&) const;
00159
00160
00161 PIDPriority GetPIDPriority(uint pid) const;
00162
00163
00164 void SetVersionPAT(uint tsid, int version, uint last_section)
00165 {
00166 if (VersionPAT(tsid) == version)
00167 return;
00168 _pat_version[tsid] = version;
00169 init_sections(_pat_section_seen[tsid], last_section);
00170 }
00171 int VersionPAT(uint tsid) const
00172 {
00173 const QMap<uint, int>::const_iterator it = _pat_version.find(tsid);
00174 if (it == _pat_version.end())
00175 return -1;
00176 return *it;
00177 }
00178
00179 void SetVersionCAT(uint tsid, int version, uint last_section)
00180 {
00181 if (VersionCAT(tsid) == version)
00182 return;
00183 _cat_version[tsid] = version;
00184 init_sections(_cat_section_seen[tsid], last_section);
00185 }
00186 int VersionCAT(uint tsid) const
00187 {
00188 const QMap<uint, int>::const_iterator it = _cat_version.find(tsid);
00189 if (it == _cat_version.end())
00190 return -1;
00191 return *it;
00192 }
00193
00194 void SetVersionPMT(uint program_num, int version, uint last_section)
00195 {
00196 if (VersionPMT(program_num) == version)
00197 return;
00198 _pmt_version[program_num] = version;
00199 init_sections(_pmt_section_seen[program_num], last_section);
00200 }
00201 int VersionPMT(uint prog_num) const
00202 {
00203 const QMap<uint, int>::const_iterator it = _pmt_version.find(prog_num);
00204 if (it == _pmt_version.end())
00205 return -1;
00206 return *it;
00207 }
00208
00209
00210 void SetPATSectionSeen(uint tsid, uint section);
00211 bool PATSectionSeen( uint tsid, uint section) const;
00212 bool HasAllPATSections(uint tsid) const;
00213
00214 void SetCATSectionSeen(uint tsid, uint section);
00215 bool CATSectionSeen( uint tsid, uint section) const;
00216 bool HasAllCATSections(uint tsid) const;
00217
00218 void SetPMTSectionSeen(uint prog_num, uint section);
00219 bool PMTSectionSeen( uint prog_num, uint section) const;
00220 bool HasAllPMTSections(uint prog_num) const;
00221
00222
00223 bool HasProgram(uint progNum) const;
00224
00225 bool HasCachedAllPAT(uint tsid) const;
00226 bool HasCachedAnyPAT(uint tsid) const;
00227 bool HasCachedAnyPAT(void) const;
00228
00229 bool HasCachedAllCAT(uint tsid) const;
00230 bool HasCachedAnyCAT(uint tsid) const;
00231 bool HasCachedAnyCAT(void) const;
00232
00233 bool HasCachedAllPMT(uint program_num) const;
00234 bool HasCachedAnyPMT(uint program_num) const;
00235 bool HasCachedAllPMTs(void) const;
00236 bool HasCachedAnyPMTs(void) const;
00237
00238 pat_ptr_t GetCachedPAT(uint tsid, uint section_num) const;
00239 pat_vec_t GetCachedPATs(uint tsid) const;
00240 pat_vec_t GetCachedPATs(void) const;
00241 pat_map_t GetCachedPATMap(void) const;
00242
00243 cat_ptr_t GetCachedCAT(uint tsid, uint section_num) const;
00244 cat_vec_t GetCachedCATs(uint tsid) const;
00245 cat_vec_t GetCachedCATs(void) const;
00246 cat_map_t GetCachedCATMap(void) const;
00247
00248 pmt_ptr_t GetCachedPMT(uint program_num, uint section_num) const;
00249 pmt_vec_t GetCachedPMTs(void) const;
00250 pmt_map_t GetCachedPMTMap(void) const;
00251
00252 virtual void ReturnCachedTable(const PSIPTable *psip) const;
00253 virtual void ReturnCachedPATTables(pat_vec_t&) const;
00254 virtual void ReturnCachedPATTables(pat_map_t&) const;
00255 virtual void ReturnCachedCATTables(cat_vec_t&) const;
00256 virtual void ReturnCachedCATTables(cat_map_t&) const;
00257 virtual void ReturnCachedPMTTables(pmt_vec_t&) const;
00258 virtual void ReturnCachedPMTTables(pmt_map_t&) const;
00259
00260
00261 void AddEncryptionTestPID(uint pnum, uint pid, bool isvideo);
00262 void RemoveEncryptionTestPIDs(uint pnum);
00263 bool IsEncryptionTestPID(uint pid) const;
00264
00265 void TestDecryption(const ProgramMapTable* pmt);
00266 void ResetDecryptionMonitoringState(void);
00267
00268 bool IsProgramDecrypted(uint pnum) const;
00269 bool IsProgramEncrypted(uint pnum) const;
00270
00271
00272 void AddMPEGListener(MPEGStreamListener*);
00273 void RemoveMPEGListener(MPEGStreamListener*);
00274 void UpdatePAT(const ProgramAssociationTable*);
00275 void UpdateCAT(const ConditionalAccessTable*);
00276 void UpdatePMT(uint program_num, const ProgramMapTable*);
00277
00278 void AddWritingListener(TSPacketListener*);
00279 void RemoveWritingListener(TSPacketListener*);
00280
00281
00282 void AddMPEGSPListener(MPEGSingleProgramStreamListener*);
00283 void RemoveMPEGSPListener(MPEGSingleProgramStreamListener*);
00284 void AddAVListener(TSPacketListenerAV*);
00285 void RemoveAVListener(TSPacketListenerAV*);
00286 void UpdatePATSingleProgram(ProgramAssociationTable*);
00287 void UpdatePMTSingleProgram(ProgramMapTable*);
00288
00289 public:
00290
00291 void SetDesiredProgram(int p);
00292 inline void SetPATSingleProgram(ProgramAssociationTable*);
00293 inline void SetPMTSingleProgram(ProgramMapTable*);
00294 void SetVideoStreamsRequired(uint num)
00295 { _pmt_single_program_num_video = num; }
00296 uint GetVideoStreamsRequired() const
00297 { return _pmt_single_program_num_video; }
00298 void SetAudioStreamsRequired(uint num)
00299 { _pmt_single_program_num_audio = num; }
00300 uint GetAudioStreamsRequired() const
00301 { return _pmt_single_program_num_audio; }
00302 void SetRecordingType(const QString &recording_type);
00303
00304
00305 int DesiredProgram(void) const { return _desired_program; }
00306 uint VideoPIDSingleProgram(void) const { return _pid_video_single_program; }
00307 QString GetRecordingType(void) const;
00308
00309 const ProgramAssociationTable* PATSingleProgram(void) const
00310 { return _pat_single_program; }
00311 const ProgramMapTable* PMTSingleProgram(void) const
00312 { return _pmt_single_program; }
00313
00314 ProgramAssociationTable* PATSingleProgram(void)
00315 { return _pat_single_program; }
00316 ProgramMapTable* PMTSingleProgram(void)
00317 { return _pmt_single_program; }
00318
00319
00320 int VersionPATSingleProgram(void) const;
00321 int VersionPMTSingleProgram(void) const;
00322
00323 bool CreatePATSingleProgram(const ProgramAssociationTable&);
00324 bool CreatePMTSingleProgram(const ProgramMapTable&);
00325
00326 protected:
00327
00328 PSIPTable* AssemblePSIP(const TSPacket* tspacket, bool& moreTablePackets);
00329 bool AssemblePSIP(PSIPTable& psip, TSPacket* tspacket);
00330 void SavePartialPSIP(uint pid, PSIPTable* packet);
00331 PSIPTable* GetPartialPSIP(uint pid)
00332 { return _partial_psip_packet_cache[pid]; }
00333 void ClearPartialPSIP(uint pid)
00334 { _partial_psip_packet_cache.remove(pid); }
00335 void DeletePartialPSIP(uint pid);
00336 void ProcessPAT(const ProgramAssociationTable *pat);
00337 void ProcessCAT(const ConditionalAccessTable *cat);
00338 void ProcessPMT(const ProgramMapTable *pmt);
00339 void ProcessEncryptedPacket(const TSPacket&);
00340
00341 static int ResyncStream(const unsigned char *buffer, int curr_pos, int len);
00342
00343 void UpdateTimeOffset(uint64_t si_utc_time);
00344
00345
00346 void IncrementRefCnt(const PSIPTable *psip) const;
00347 virtual bool DeleteCachedTable(PSIPTable *psip) const;
00348 void CachePAT(const ProgramAssociationTable *pat);
00349 void CacheCAT(const ConditionalAccessTable *pat);
00350 void CachePMT(const ProgramMapTable *pmt);
00351
00352 protected:
00353 QString _sistandard;
00354
00355 bool _have_CRC_bug;
00356
00357 int _local_utc_offset;
00358
00359 mutable QMutex _si_time_lock;
00360 uint _si_time_offset_cnt;
00361 uint _si_time_offset_indx;
00362 double _si_time_offsets[16];
00363
00364
00365 EITHelper *_eit_helper;
00366 float _eit_rate;
00367
00368
00369 pid_map_t _pids_listening;
00370 pid_map_t _pids_notlistening;
00371 pid_map_t _pids_writing;
00372 pid_map_t _pids_audio;
00373 bool _listening_disabled;
00374
00375
00376 mutable QMutex _encryption_lock;
00377 QMap<uint, CryptInfo> _encryption_pid_to_info;
00378 QMap<uint, uint_vec_t> _encryption_pnum_to_pids;
00379 QMap<uint, uint_vec_t> _encryption_pid_to_pnums;
00380 QMap<uint, CryptStatus> _encryption_pnum_to_status;
00381
00382
00383 mutable QMutex _listener_lock;
00384 mpeg_listener_vec_t _mpeg_listeners;
00385 mpeg_sp_listener_vec_t _mpeg_sp_listeners;
00386 ts_listener_vec_t _ts_writing_listeners;
00387 ts_av_listener_vec_t _ts_av_listeners;
00388
00389
00390 QMap<uint, int> _pat_version;
00391 QMap<uint, int> _cat_version;
00392 QMap<uint, int> _pmt_version;
00393
00394 sections_map_t _pat_section_seen;
00395 sections_map_t _cat_section_seen;
00396 sections_map_t _pmt_section_seen;
00397
00398
00399 pid_psip_map_t _partial_psip_packet_cache;
00400
00401
00402 bool _cache_tables;
00403 mutable QMutex _cache_lock;
00404 mutable pat_cache_t _cached_pats;
00405 mutable cat_cache_t _cached_cats;
00406 mutable pmt_cache_t _cached_pmts;
00407 mutable psip_refcnt_map_t _cached_ref_cnt;
00408 mutable psip_refcnt_map_t _cached_slated_for_deletion;
00409
00410
00411 int _desired_program;
00412 QString _recording_type;
00413 bool _strip_pmt_descriptors;
00414 bool _normalize_stream_type;
00415 uint _pid_video_single_program;
00416 uint _pid_pmt_single_program;
00417 uint _pmt_single_program_num_video;
00418 uint _pmt_single_program_num_audio;
00419 ProgramAssociationTable *_pat_single_program;
00420 ProgramMapTable *_pmt_single_program;
00421
00422
00423 private:
00424 bool _invalid_pat_seen;
00425 bool _invalid_pat_warning;
00426 MythTimer _invalid_pat_timer;
00427
00428 protected:
00429 static const unsigned char bit_sel[8];
00430 };
00431
00432 #include "mpegtables.h"
00433
00434 inline void MPEGStreamData::SetPATSingleProgram(ProgramAssociationTable* pat)
00435 {
00436 if (_pat_single_program)
00437 delete _pat_single_program;
00438 _pat_single_program = pat;
00439 }
00440
00441 inline void MPEGStreamData::SetPMTSingleProgram(ProgramMapTable* pmt)
00442 {
00443 if (_pmt_single_program)
00444 delete _pmt_single_program;
00445 _pmt_single_program = pmt;
00446 }
00447
00448 inline int MPEGStreamData::VersionPATSingleProgram() const
00449 {
00450 return (_pat_single_program) ? int(_pat_single_program->Version()) : -1;
00451 }
00452
00453 inline int MPEGStreamData::VersionPMTSingleProgram() const
00454 {
00455 return (_pmt_single_program) ? int(_pmt_single_program->Version()) : -1;
00456 }
00457
00458 inline void MPEGStreamData::HandleAdaptationFieldControl(const TSPacket*)
00459 {
00460
00461
00462 }
00463
00464 #endif